@stream-io/video-filters-web 0.10.0 → 1.0.0-beta.1
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/CHANGELOG.md +13 -1
- package/README.md +1 -1
- package/dist/esm/index.js +1 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/src/compatibility.js +1 -18
- package/dist/esm/src/compatibility.js.map +1 -1
- package/dist/esm/src/version.js +1 -1
- package/dist/index.cjs.js +1 -1559
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/src/compatibility.d.ts +0 -5
- package/index.ts +0 -3
- package/package.json +2 -5
- package/src/compatibility.ts +0 -22
- package/dist/esm/src/legacy/createRenderer.js +0 -33
- package/dist/esm/src/legacy/createRenderer.js.map +0 -1
- package/dist/esm/src/legacy/helpers/webglHelper.js +0 -94
- package/dist/esm/src/legacy/helpers/webglHelper.js.map +0 -1
- package/dist/esm/src/legacy/segmentation.js +0 -14
- package/dist/esm/src/legacy/segmentation.js.map +0 -1
- package/dist/esm/src/legacy/tflite-simd.js +0 -728
- package/dist/esm/src/legacy/tflite-simd.js.map +0 -1
- package/dist/esm/src/legacy/tflite.js +0 -31
- package/dist/esm/src/legacy/tflite.js.map +0 -1
- package/dist/esm/src/legacy/webgl2/backgroundBlurStage.js +0 -202
- package/dist/esm/src/legacy/webgl2/backgroundBlurStage.js.map +0 -1
- package/dist/esm/src/legacy/webgl2/backgroundImageStage.js +0 -157
- package/dist/esm/src/legacy/webgl2/backgroundImageStage.js.map +0 -1
- package/dist/esm/src/legacy/webgl2/jointBilateralFilterStage.js +0 -113
- package/dist/esm/src/legacy/webgl2/jointBilateralFilterStage.js.map +0 -1
- package/dist/esm/src/legacy/webgl2/resizingStage.js +0 -57
- package/dist/esm/src/legacy/webgl2/resizingStage.js.map +0 -1
- package/dist/esm/src/legacy/webgl2/softmaxStage.js +0 -51
- package/dist/esm/src/legacy/webgl2/softmaxStage.js.map +0 -1
- package/dist/esm/src/legacy/webgl2/webgl2Pipeline.js +0 -105
- package/dist/esm/src/legacy/webgl2/webgl2Pipeline.js.map +0 -1
- package/dist/src/legacy/createRenderer.d.ts +0 -16
- package/dist/src/legacy/helpers/webglHelper.d.ts +0 -17
- package/dist/src/legacy/segmentation.d.ts +0 -9
- package/dist/src/legacy/tflite.d.ts +0 -18
- package/dist/src/legacy/webgl2/backgroundBlurStage.d.ts +0 -7
- package/dist/src/legacy/webgl2/backgroundImageStage.d.ts +0 -8
- package/dist/src/legacy/webgl2/jointBilateralFilterStage.d.ts +0 -7
- package/dist/src/legacy/webgl2/resizingStage.d.ts +0 -6
- package/dist/src/legacy/webgl2/softmaxStage.d.ts +0 -6
- package/dist/src/legacy/webgl2/webgl2Pipeline.d.ts +0 -8
- package/src/legacy/createRenderer.ts +0 -73
- package/src/legacy/helpers/webglHelper.ts +0 -144
- package/src/legacy/segmentation.ts +0 -18
- package/src/legacy/tflite-simd.js +0 -874
- package/src/legacy/tflite.ts +0 -59
- package/src/legacy/webgl2/backgroundBlurStage.ts +0 -315
- package/src/legacy/webgl2/backgroundImageStage.ts +0 -222
- package/src/legacy/webgl2/jointBilateralFilterStage.ts +0 -159
- package/src/legacy/webgl2/resizingStage.ts +0 -106
- package/src/legacy/webgl2/softmaxStage.ts +0 -103
- package/src/legacy/webgl2/webgl2Pipeline.ts +0 -203
- package/tf/models/segm_full_v679.tflite +0 -0
- package/tf/tflite/tflite-simd.wasm +0 -0
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { compileShader, createPipelineStageProgram, glsl } from '../helpers/webglHelper.js';
|
|
2
|
-
|
|
3
|
-
function buildJointBilateralFilterStage(gl, vertexShader, positionBuffer, texCoordBuffer, inputTexture, outputTexture, canvas, segmentationConfig) {
|
|
4
|
-
const fragmentShaderSource = glsl `#version 300 es
|
|
5
|
-
|
|
6
|
-
precision highp float;
|
|
7
|
-
|
|
8
|
-
uniform sampler2D u_inputFrame;
|
|
9
|
-
uniform sampler2D u_segmentationMask;
|
|
10
|
-
uniform vec2 u_texelSize;
|
|
11
|
-
uniform float u_step;
|
|
12
|
-
uniform float u_radius;
|
|
13
|
-
uniform float u_offset;
|
|
14
|
-
uniform float u_sigmaTexel;
|
|
15
|
-
uniform float u_sigmaColor;
|
|
16
|
-
|
|
17
|
-
in vec2 v_texCoord;
|
|
18
|
-
out vec4 outColor;
|
|
19
|
-
|
|
20
|
-
float gaussian(float x, float sigma) {
|
|
21
|
-
float coeff = -0.5 / (sigma * sigma * 4.0 + 1.0e-6);
|
|
22
|
-
return exp((x * x) * coeff);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
void main() {
|
|
26
|
-
vec2 centerCoord = v_texCoord;
|
|
27
|
-
vec3 centerColor = texture(u_inputFrame, centerCoord).rgb;
|
|
28
|
-
float newVal = 0.0;
|
|
29
|
-
|
|
30
|
-
float spaceWeight = 0.0;
|
|
31
|
-
float colorWeight = 0.0;
|
|
32
|
-
float totalWeight = 0.0;
|
|
33
|
-
|
|
34
|
-
// Subsample kernel space.
|
|
35
|
-
for (float i = -u_radius + u_offset; i <= u_radius; i += u_step) {
|
|
36
|
-
for (float j = -u_radius + u_offset; j <= u_radius; j += u_step) {
|
|
37
|
-
vec2 shift = vec2(j, i) * u_texelSize;
|
|
38
|
-
vec2 coord = vec2(centerCoord + shift);
|
|
39
|
-
vec3 frameColor = texture(u_inputFrame, coord).rgb;
|
|
40
|
-
float outVal = texture(u_segmentationMask, coord).a;
|
|
41
|
-
|
|
42
|
-
spaceWeight = gaussian(distance(centerCoord, coord), u_sigmaTexel);
|
|
43
|
-
colorWeight = gaussian(distance(centerColor, frameColor), u_sigmaColor);
|
|
44
|
-
totalWeight += spaceWeight * colorWeight;
|
|
45
|
-
|
|
46
|
-
newVal += spaceWeight * colorWeight * outVal;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
newVal /= totalWeight;
|
|
50
|
-
|
|
51
|
-
outColor = vec4(vec3(0.0), newVal);
|
|
52
|
-
}
|
|
53
|
-
`;
|
|
54
|
-
const { width: segmentationWidth, height: segmentationHeight } = segmentationConfig;
|
|
55
|
-
const { width: outputWidth, height: outputHeight } = canvas;
|
|
56
|
-
const texelWidth = 1 / outputWidth;
|
|
57
|
-
const texelHeight = 1 / outputHeight;
|
|
58
|
-
const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
|
|
59
|
-
const program = createPipelineStageProgram(gl, vertexShader, fragmentShader, positionBuffer, texCoordBuffer);
|
|
60
|
-
const inputFrameLocation = gl.getUniformLocation(program, 'u_inputFrame');
|
|
61
|
-
const segmentationMaskLocation = gl.getUniformLocation(program, 'u_segmentationMask');
|
|
62
|
-
const texelSizeLocation = gl.getUniformLocation(program, 'u_texelSize');
|
|
63
|
-
const stepLocation = gl.getUniformLocation(program, 'u_step');
|
|
64
|
-
const radiusLocation = gl.getUniformLocation(program, 'u_radius');
|
|
65
|
-
const offsetLocation = gl.getUniformLocation(program, 'u_offset');
|
|
66
|
-
const sigmaTexelLocation = gl.getUniformLocation(program, 'u_sigmaTexel');
|
|
67
|
-
const sigmaColorLocation = gl.getUniformLocation(program, 'u_sigmaColor');
|
|
68
|
-
const frameBuffer = gl.createFramebuffer();
|
|
69
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
|
|
70
|
-
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, outputTexture, 0);
|
|
71
|
-
gl.useProgram(program);
|
|
72
|
-
gl.uniform1i(inputFrameLocation, 0);
|
|
73
|
-
gl.uniform1i(segmentationMaskLocation, 1);
|
|
74
|
-
gl.uniform2f(texelSizeLocation, texelWidth, texelHeight);
|
|
75
|
-
// Ensures default values are configured to prevent infinite
|
|
76
|
-
// loop in fragment shader
|
|
77
|
-
updateSigmaSpace(0);
|
|
78
|
-
updateSigmaColor(0);
|
|
79
|
-
function render() {
|
|
80
|
-
gl.viewport(0, 0, outputWidth, outputHeight);
|
|
81
|
-
gl.useProgram(program);
|
|
82
|
-
gl.activeTexture(gl.TEXTURE1);
|
|
83
|
-
gl.bindTexture(gl.TEXTURE_2D, inputTexture);
|
|
84
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
|
|
85
|
-
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
86
|
-
}
|
|
87
|
-
function updateSigmaSpace(sigmaSpace) {
|
|
88
|
-
sigmaSpace *= Math.max(outputWidth / segmentationWidth, outputHeight / segmentationHeight);
|
|
89
|
-
const kSparsityFactor = 0.66; // Higher is sparser.
|
|
90
|
-
const step = Math.max(1, Math.sqrt(sigmaSpace) * kSparsityFactor);
|
|
91
|
-
const radius = sigmaSpace;
|
|
92
|
-
const offset = step > 1 ? step * 0.5 : 0;
|
|
93
|
-
const sigmaTexel = Math.max(texelWidth, texelHeight) * sigmaSpace;
|
|
94
|
-
gl.useProgram(program);
|
|
95
|
-
gl.uniform1f(stepLocation, step);
|
|
96
|
-
gl.uniform1f(radiusLocation, radius);
|
|
97
|
-
gl.uniform1f(offsetLocation, offset);
|
|
98
|
-
gl.uniform1f(sigmaTexelLocation, sigmaTexel);
|
|
99
|
-
}
|
|
100
|
-
function updateSigmaColor(sigmaColor) {
|
|
101
|
-
gl.useProgram(program);
|
|
102
|
-
gl.uniform1f(sigmaColorLocation, sigmaColor);
|
|
103
|
-
}
|
|
104
|
-
function cleanUp() {
|
|
105
|
-
gl.deleteFramebuffer(frameBuffer);
|
|
106
|
-
gl.deleteProgram(program);
|
|
107
|
-
gl.deleteShader(fragmentShader);
|
|
108
|
-
}
|
|
109
|
-
return { render, updateSigmaSpace, updateSigmaColor, cleanUp };
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export { buildJointBilateralFilterStage };
|
|
113
|
-
//# sourceMappingURL=jointBilateralFilterStage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jointBilateralFilterStage.js","sources":["../../../../../../../src/legacy/webgl2/jointBilateralFilterStage.ts"],"sourcesContent":["import {\n compileShader,\n createPipelineStageProgram,\n glsl,\n} from '../helpers/webglHelper';\nimport { SegmentationParams } from '../segmentation';\n\nexport function buildJointBilateralFilterStage(\n gl: WebGL2RenderingContext,\n vertexShader: WebGLShader,\n positionBuffer: WebGLBuffer,\n texCoordBuffer: WebGLBuffer,\n inputTexture: WebGLTexture,\n outputTexture: WebGLTexture,\n canvas: HTMLCanvasElement,\n segmentationConfig: SegmentationParams,\n) {\n const fragmentShaderSource = glsl`#version 300 es\n\n precision highp float;\n\n uniform sampler2D u_inputFrame;\n uniform sampler2D u_segmentationMask;\n uniform vec2 u_texelSize;\n uniform float u_step;\n uniform float u_radius;\n uniform float u_offset;\n uniform float u_sigmaTexel;\n uniform float u_sigmaColor;\n\n in vec2 v_texCoord;\n out vec4 outColor;\n\n float gaussian(float x, float sigma) {\n float coeff = -0.5 / (sigma * sigma * 4.0 + 1.0e-6);\n return exp((x * x) * coeff);\n }\n\n void main() {\n vec2 centerCoord = v_texCoord;\n vec3 centerColor = texture(u_inputFrame, centerCoord).rgb;\n float newVal = 0.0;\n\n float spaceWeight = 0.0;\n float colorWeight = 0.0;\n float totalWeight = 0.0;\n\n // Subsample kernel space.\n for (float i = -u_radius + u_offset; i <= u_radius; i += u_step) {\n for (float j = -u_radius + u_offset; j <= u_radius; j += u_step) {\n vec2 shift = vec2(j, i) * u_texelSize;\n vec2 coord = vec2(centerCoord + shift);\n vec3 frameColor = texture(u_inputFrame, coord).rgb;\n float outVal = texture(u_segmentationMask, coord).a;\n\n spaceWeight = gaussian(distance(centerCoord, coord), u_sigmaTexel);\n colorWeight = gaussian(distance(centerColor, frameColor), u_sigmaColor);\n totalWeight += spaceWeight * colorWeight;\n\n newVal += spaceWeight * colorWeight * outVal;\n }\n }\n newVal /= totalWeight;\n\n outColor = vec4(vec3(0.0), newVal);\n }\n `;\n\n const { width: segmentationWidth, height: segmentationHeight } =\n segmentationConfig;\n const { width: outputWidth, height: outputHeight } = canvas;\n const texelWidth = 1 / outputWidth;\n const texelHeight = 1 / outputHeight;\n\n const fragmentShader = compileShader(\n gl,\n gl.FRAGMENT_SHADER,\n fragmentShaderSource,\n );\n const program = createPipelineStageProgram(\n gl,\n vertexShader,\n fragmentShader,\n positionBuffer,\n texCoordBuffer,\n );\n const inputFrameLocation = gl.getUniformLocation(program, 'u_inputFrame');\n const segmentationMaskLocation = gl.getUniformLocation(\n program,\n 'u_segmentationMask',\n );\n const texelSizeLocation = gl.getUniformLocation(program, 'u_texelSize');\n const stepLocation = gl.getUniformLocation(program, 'u_step');\n const radiusLocation = gl.getUniformLocation(program, 'u_radius');\n const offsetLocation = gl.getUniformLocation(program, 'u_offset');\n const sigmaTexelLocation = gl.getUniformLocation(program, 'u_sigmaTexel');\n const sigmaColorLocation = gl.getUniformLocation(program, 'u_sigmaColor');\n\n const frameBuffer = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n outputTexture,\n 0,\n );\n\n gl.useProgram(program);\n gl.uniform1i(inputFrameLocation, 0);\n gl.uniform1i(segmentationMaskLocation, 1);\n gl.uniform2f(texelSizeLocation, texelWidth, texelHeight);\n\n // Ensures default values are configured to prevent infinite\n // loop in fragment shader\n updateSigmaSpace(0);\n updateSigmaColor(0);\n\n function render() {\n gl.viewport(0, 0, outputWidth, outputHeight);\n gl.useProgram(program);\n gl.activeTexture(gl.TEXTURE1);\n gl.bindTexture(gl.TEXTURE_2D, inputTexture);\n gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n }\n\n function updateSigmaSpace(sigmaSpace: number) {\n sigmaSpace *= Math.max(\n outputWidth / segmentationWidth,\n outputHeight / segmentationHeight,\n );\n\n const kSparsityFactor = 0.66; // Higher is sparser.\n const step = Math.max(1, Math.sqrt(sigmaSpace) * kSparsityFactor);\n const radius = sigmaSpace;\n const offset = step > 1 ? step * 0.5 : 0;\n const sigmaTexel = Math.max(texelWidth, texelHeight) * sigmaSpace;\n\n gl.useProgram(program);\n gl.uniform1f(stepLocation, step);\n gl.uniform1f(radiusLocation, radius);\n gl.uniform1f(offsetLocation, offset);\n gl.uniform1f(sigmaTexelLocation, sigmaTexel);\n }\n\n function updateSigmaColor(sigmaColor: number) {\n gl.useProgram(program);\n gl.uniform1f(sigmaColorLocation, sigmaColor);\n }\n\n function cleanUp() {\n gl.deleteFramebuffer(frameBuffer);\n gl.deleteProgram(program);\n gl.deleteShader(fragmentShader);\n }\n\n return { render, updateSigmaSpace, updateSigmaColor, cleanUp };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { compileShader, createPipelineStageProgram, createTexture, glsl, readPixelsAsync } from '../helpers/webglHelper.js';
|
|
2
|
-
|
|
3
|
-
function buildResizingStage(gl, vertexShader, positionBuffer, texCoordBuffer, tflite, segmentationConfig, onError) {
|
|
4
|
-
const fragmentShaderSource = glsl `#version 300 es
|
|
5
|
-
|
|
6
|
-
precision highp float;
|
|
7
|
-
uniform sampler2D u_inputFrame;
|
|
8
|
-
in vec2 v_texCoord;
|
|
9
|
-
out vec4 outColor;
|
|
10
|
-
|
|
11
|
-
void main() {
|
|
12
|
-
outColor = texture(u_inputFrame, v_texCoord);
|
|
13
|
-
}
|
|
14
|
-
`;
|
|
15
|
-
// TFLite memory will be accessed as float32
|
|
16
|
-
const tfliteInputMemoryOffset = tflite._getInputMemoryOffset() / 4;
|
|
17
|
-
const { width: outputWidth, height: outputHeight } = segmentationConfig;
|
|
18
|
-
const outputPixelCount = outputWidth * outputHeight;
|
|
19
|
-
const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
|
|
20
|
-
const program = createPipelineStageProgram(gl, vertexShader, fragmentShader, positionBuffer, texCoordBuffer);
|
|
21
|
-
const inputFrameLocation = gl.getUniformLocation(program, 'u_inputFrame');
|
|
22
|
-
const outputTexture = createTexture(gl, gl.RGBA8, outputWidth, outputHeight);
|
|
23
|
-
const frameBuffer = gl.createFramebuffer();
|
|
24
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
|
|
25
|
-
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, outputTexture, 0);
|
|
26
|
-
const outputPixels = new Uint8Array(outputPixelCount * 4);
|
|
27
|
-
gl.useProgram(program);
|
|
28
|
-
gl.uniform1i(inputFrameLocation, 0);
|
|
29
|
-
function render() {
|
|
30
|
-
gl.viewport(0, 0, outputWidth, outputHeight);
|
|
31
|
-
gl.useProgram(program);
|
|
32
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
|
|
33
|
-
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
34
|
-
// Downloads pixels asynchronously from GPU while rendering the current frame.
|
|
35
|
-
// The pixels will be available in the next frame render which results
|
|
36
|
-
// in offsets in the segmentation output but increases the frame rate.
|
|
37
|
-
readPixelsAsync(gl, 0, 0, outputWidth, outputHeight, gl.RGBA, gl.UNSIGNED_BYTE, outputPixels).catch((error) => {
|
|
38
|
-
});
|
|
39
|
-
for (let i = 0; i < outputPixelCount; i++) {
|
|
40
|
-
const tfliteIndex = tfliteInputMemoryOffset + i * 3;
|
|
41
|
-
const outputIndex = i * 4;
|
|
42
|
-
tflite.HEAPF32[tfliteIndex] = outputPixels[outputIndex] / 255;
|
|
43
|
-
tflite.HEAPF32[tfliteIndex + 1] = outputPixels[outputIndex + 1] / 255;
|
|
44
|
-
tflite.HEAPF32[tfliteIndex + 2] = outputPixels[outputIndex + 2] / 255;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
function cleanUp() {
|
|
48
|
-
gl.deleteFramebuffer(frameBuffer);
|
|
49
|
-
gl.deleteTexture(outputTexture);
|
|
50
|
-
gl.deleteProgram(program);
|
|
51
|
-
gl.deleteShader(fragmentShader);
|
|
52
|
-
}
|
|
53
|
-
return { render, cleanUp };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export { buildResizingStage };
|
|
57
|
-
//# sourceMappingURL=resizingStage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resizingStage.js","sources":["../../../../../../../src/legacy/webgl2/resizingStage.ts"],"sourcesContent":["import { TFLite } from '../tflite';\nimport {\n compileShader,\n createPipelineStageProgram,\n createTexture,\n glsl,\n readPixelsAsync,\n} from '../helpers/webglHelper';\nimport { SegmentationParams } from '../segmentation';\n\nexport function buildResizingStage(\n gl: WebGL2RenderingContext,\n vertexShader: WebGLShader,\n positionBuffer: WebGLBuffer,\n texCoordBuffer: WebGLBuffer,\n tflite: TFLite,\n segmentationConfig: SegmentationParams,\n onError?: (error: any) => void,\n) {\n const fragmentShaderSource = glsl`#version 300 es\n\n precision highp float;\n uniform sampler2D u_inputFrame;\n in vec2 v_texCoord;\n out vec4 outColor;\n\n void main() {\n outColor = texture(u_inputFrame, v_texCoord);\n }\n `;\n\n // TFLite memory will be accessed as float32\n const tfliteInputMemoryOffset = tflite._getInputMemoryOffset() / 4;\n\n const { width: outputWidth, height: outputHeight } = segmentationConfig;\n const outputPixelCount = outputWidth * outputHeight;\n\n const fragmentShader = compileShader(\n gl,\n gl.FRAGMENT_SHADER,\n fragmentShaderSource,\n );\n const program = createPipelineStageProgram(\n gl,\n vertexShader,\n fragmentShader,\n positionBuffer,\n texCoordBuffer,\n );\n const inputFrameLocation = gl.getUniformLocation(program, 'u_inputFrame');\n const outputTexture = createTexture(gl, gl.RGBA8, outputWidth, outputHeight);\n\n const frameBuffer = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n outputTexture,\n 0,\n );\n const outputPixels = new Uint8Array(outputPixelCount * 4);\n\n gl.useProgram(program);\n gl.uniform1i(inputFrameLocation, 0);\n\n function render() {\n gl.viewport(0, 0, outputWidth, outputHeight);\n gl.useProgram(program);\n gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n\n // Downloads pixels asynchronously from GPU while rendering the current frame.\n // The pixels will be available in the next frame render which results\n // in offsets in the segmentation output but increases the frame rate.\n readPixelsAsync(\n gl,\n 0,\n 0,\n outputWidth,\n outputHeight,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n outputPixels,\n ).catch((error: any) => {\n onError?.(error);\n });\n\n for (let i = 0; i < outputPixelCount; i++) {\n const tfliteIndex = tfliteInputMemoryOffset + i * 3;\n const outputIndex = i * 4;\n tflite.HEAPF32[tfliteIndex] = outputPixels[outputIndex] / 255;\n tflite.HEAPF32[tfliteIndex + 1] = outputPixels[outputIndex + 1] / 255;\n tflite.HEAPF32[tfliteIndex + 2] = outputPixels[outputIndex + 2] / 255;\n }\n }\n\n function cleanUp() {\n gl.deleteFramebuffer(frameBuffer);\n gl.deleteTexture(outputTexture);\n gl.deleteProgram(program);\n gl.deleteShader(fragmentShader);\n }\n\n return { render, cleanUp };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { compileShader, createPipelineStageProgram, createTexture, glsl } from '../helpers/webglHelper.js';
|
|
2
|
-
|
|
3
|
-
function buildSoftmaxStage(gl, vertexShader, positionBuffer, texCoordBuffer, tflite, outputTexture, segmentationConfig) {
|
|
4
|
-
const fragmentShaderSource = glsl `#version 300 es
|
|
5
|
-
|
|
6
|
-
precision highp float;
|
|
7
|
-
|
|
8
|
-
uniform sampler2D u_inputSegmentation;
|
|
9
|
-
in vec2 v_texCoord;
|
|
10
|
-
out vec4 outColor;
|
|
11
|
-
|
|
12
|
-
void main() {
|
|
13
|
-
vec2 segmentation = texture(u_inputSegmentation, v_texCoord).rg;
|
|
14
|
-
float shift = max(segmentation.r, segmentation.g);
|
|
15
|
-
float backgroundExp = exp(segmentation.r - shift);
|
|
16
|
-
float personExp = exp(segmentation.g - shift);
|
|
17
|
-
outColor = vec4(vec3(0.0), personExp / (backgroundExp + personExp));
|
|
18
|
-
}
|
|
19
|
-
`;
|
|
20
|
-
// TFLite memory will be accessed as float32
|
|
21
|
-
const tfliteOutputMemoryOffset = tflite._getOutputMemoryOffset() / 4;
|
|
22
|
-
const { width: segmentationWidth, height: segmentationHeight } = segmentationConfig;
|
|
23
|
-
const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
|
|
24
|
-
const program = createPipelineStageProgram(gl, vertexShader, fragmentShader, positionBuffer, texCoordBuffer);
|
|
25
|
-
const inputLocation = gl.getUniformLocation(program, 'u_inputSegmentation');
|
|
26
|
-
const inputTexture = createTexture(gl, gl.RG32F, segmentationWidth, segmentationHeight);
|
|
27
|
-
const frameBuffer = gl.createFramebuffer();
|
|
28
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
|
|
29
|
-
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, outputTexture, 0);
|
|
30
|
-
gl.useProgram(program);
|
|
31
|
-
gl.uniform1i(inputLocation, 1);
|
|
32
|
-
function render() {
|
|
33
|
-
gl.viewport(0, 0, segmentationWidth, segmentationHeight);
|
|
34
|
-
gl.useProgram(program);
|
|
35
|
-
gl.activeTexture(gl.TEXTURE1);
|
|
36
|
-
gl.bindTexture(gl.TEXTURE_2D, inputTexture);
|
|
37
|
-
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, segmentationWidth, segmentationHeight, gl.RG, gl.FLOAT, tflite.HEAPF32, tfliteOutputMemoryOffset);
|
|
38
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
|
|
39
|
-
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
40
|
-
}
|
|
41
|
-
function cleanUp() {
|
|
42
|
-
gl.deleteFramebuffer(frameBuffer);
|
|
43
|
-
gl.deleteTexture(inputTexture);
|
|
44
|
-
gl.deleteProgram(program);
|
|
45
|
-
gl.deleteShader(fragmentShader);
|
|
46
|
-
}
|
|
47
|
-
return { render, cleanUp };
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export { buildSoftmaxStage };
|
|
51
|
-
//# sourceMappingURL=softmaxStage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"softmaxStage.js","sources":["../../../../../../../src/legacy/webgl2/softmaxStage.ts"],"sourcesContent":["import { TFLite } from '../tflite';\nimport {\n compileShader,\n createPipelineStageProgram,\n createTexture,\n glsl,\n} from '../helpers/webglHelper';\nimport { SegmentationParams } from '../segmentation';\n\nexport function buildSoftmaxStage(\n gl: WebGL2RenderingContext,\n vertexShader: WebGLShader,\n positionBuffer: WebGLBuffer,\n texCoordBuffer: WebGLBuffer,\n tflite: TFLite,\n outputTexture: WebGLTexture,\n segmentationConfig: SegmentationParams,\n) {\n const fragmentShaderSource = glsl`#version 300 es\n\n precision highp float;\n\n uniform sampler2D u_inputSegmentation;\n in vec2 v_texCoord;\n out vec4 outColor;\n\n void main() {\n vec2 segmentation = texture(u_inputSegmentation, v_texCoord).rg;\n float shift = max(segmentation.r, segmentation.g);\n float backgroundExp = exp(segmentation.r - shift);\n float personExp = exp(segmentation.g - shift);\n outColor = vec4(vec3(0.0), personExp / (backgroundExp + personExp));\n }\n `;\n\n // TFLite memory will be accessed as float32\n const tfliteOutputMemoryOffset = tflite._getOutputMemoryOffset() / 4;\n const { width: segmentationWidth, height: segmentationHeight } =\n segmentationConfig;\n\n const fragmentShader = compileShader(\n gl,\n gl.FRAGMENT_SHADER,\n fragmentShaderSource,\n );\n const program = createPipelineStageProgram(\n gl,\n vertexShader,\n fragmentShader,\n positionBuffer,\n texCoordBuffer,\n );\n const inputLocation = gl.getUniformLocation(program, 'u_inputSegmentation');\n const inputTexture = createTexture(\n gl,\n gl.RG32F,\n segmentationWidth,\n segmentationHeight,\n );\n\n const frameBuffer = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n outputTexture,\n 0,\n );\n\n gl.useProgram(program);\n gl.uniform1i(inputLocation, 1);\n\n function render() {\n gl.viewport(0, 0, segmentationWidth, segmentationHeight);\n gl.useProgram(program);\n gl.activeTexture(gl.TEXTURE1);\n gl.bindTexture(gl.TEXTURE_2D, inputTexture);\n gl.texSubImage2D(\n gl.TEXTURE_2D,\n 0,\n 0,\n 0,\n segmentationWidth,\n segmentationHeight,\n gl.RG,\n gl.FLOAT,\n tflite.HEAPF32,\n tfliteOutputMemoryOffset,\n );\n gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n }\n\n function cleanUp() {\n gl.deleteFramebuffer(frameBuffer);\n gl.deleteTexture(inputTexture);\n gl.deleteProgram(program);\n gl.deleteShader(fragmentShader);\n }\n\n return { render, cleanUp };\n}\n"],"names":[],"mappings":";;AASM,SAAU,iBAAiB,CAC/B,EAA0B,EAC1B,YAAyB,EACzB,cAA2B,EAC3B,cAA2B,EAC3B,MAAc,EACd,aAA2B,EAC3B,kBAAsC,EAAA;IAEtC,MAAM,oBAAoB,GAAG,IAAI,CAAA,CAAA;;;;;;;;;;;;;;;GAehC;;IAGD,MAAM,wBAAwB,GAAG,MAAM,CAAC,sBAAsB,EAAE,GAAG,CAAC;IACpE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAC5D,kBAAkB;AAEpB,IAAA,MAAM,cAAc,GAAG,aAAa,CAClC,EAAE,EACF,EAAE,CAAC,eAAe,EAClB,oBAAoB,CACrB;AACD,IAAA,MAAM,OAAO,GAAG,0BAA0B,CACxC,EAAE,EACF,YAAY,EACZ,cAAc,EACd,cAAc,EACd,cAAc,CACf;IACD,MAAM,aAAa,GAAG,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,qBAAqB,CAAC;AAC3E,IAAA,MAAM,YAAY,GAAG,aAAa,CAChC,EAAE,EACF,EAAE,CAAC,KAAK,EACR,iBAAiB,EACjB,kBAAkB,CACnB;AAED,IAAA,MAAM,WAAW,GAAG,EAAE,CAAC,iBAAiB,EAAE;IAC1C,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC;AAC/C,IAAA,EAAE,CAAC,oBAAoB,CACrB,EAAE,CAAC,WAAW,EACd,EAAE,CAAC,iBAAiB,EACpB,EAAE,CAAC,UAAU,EACb,aAAa,EACb,CAAC,CACF;AAED,IAAA,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;AACtB,IAAA,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC;AAE9B,IAAA,SAAS,MAAM,GAAA;QACb,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,iBAAiB,EAAE,kBAAkB,CAAC;AACxD,QAAA,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;AACtB,QAAA,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC;QAC7B,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,YAAY,CAAC;AAC3C,QAAA,EAAE,CAAC,aAAa,CACd,EAAE,CAAC,UAAU,EACb,CAAC,EACD,CAAC,EACD,CAAC,EACD,iBAAiB,EACjB,kBAAkB,EAClB,EAAE,CAAC,EAAE,EACL,EAAE,CAAC,KAAK,EACR,MAAM,CAAC,OAAO,EACd,wBAAwB,CACzB;QACD,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC;QAC/C,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC;IACxC;AAEA,IAAA,SAAS,OAAO,GAAA;AACd,QAAA,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC;AACjC,QAAA,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC;AAC9B,QAAA,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC;AACzB,QAAA,EAAE,CAAC,YAAY,CAAC,cAAc,CAAC;IACjC;AAEA,IAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE;AAC5B;;;;"}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { compileShader, createTexture, glsl } from '../helpers/webglHelper.js';
|
|
2
|
-
import { buildBackgroundBlurStage } from './backgroundBlurStage.js';
|
|
3
|
-
import { buildBackgroundImageStage } from './backgroundImageStage.js';
|
|
4
|
-
import { buildJointBilateralFilterStage } from './jointBilateralFilterStage.js';
|
|
5
|
-
import { buildResizingStage } from './resizingStage.js';
|
|
6
|
-
import { buildSoftmaxStage } from './softmaxStage.js';
|
|
7
|
-
|
|
8
|
-
function buildWebGL2Pipeline(videoSource, backgroundImage, blurLevel, backgroundFilter, canvas, tflite, segmentationConfig, onError) {
|
|
9
|
-
const gl = canvas.getContext('webgl2');
|
|
10
|
-
if (!gl)
|
|
11
|
-
throw new Error('WebGL2 is not supported');
|
|
12
|
-
if (gl.isContextLost())
|
|
13
|
-
throw new Error('WebGL2 context was lost');
|
|
14
|
-
const { width: frameWidth, height: frameHeight } = videoSource;
|
|
15
|
-
const { width: segmentationWidth, height: segmentationHeight } = segmentationConfig;
|
|
16
|
-
const vertexShaderSource = glsl `#version 300 es
|
|
17
|
-
|
|
18
|
-
in vec2 a_position;
|
|
19
|
-
in vec2 a_texCoord;
|
|
20
|
-
out vec2 v_texCoord;
|
|
21
|
-
|
|
22
|
-
void main() {
|
|
23
|
-
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
24
|
-
v_texCoord = a_texCoord;
|
|
25
|
-
}
|
|
26
|
-
`;
|
|
27
|
-
const vertexShader = compileShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
|
|
28
|
-
const vertexArray = gl.createVertexArray();
|
|
29
|
-
gl.bindVertexArray(vertexArray);
|
|
30
|
-
const positionBuffer = gl.createBuffer();
|
|
31
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
|
32
|
-
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1.0, -1, -1, 1.0, 1.0, 1.0]), gl.STATIC_DRAW);
|
|
33
|
-
const texCoordBuffer = gl.createBuffer();
|
|
34
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
|
|
35
|
-
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0]), gl.STATIC_DRAW);
|
|
36
|
-
// We don't use texStorage2D here because texImage2D seems faster
|
|
37
|
-
// to upload video texture than texSubImage2D even though the latter
|
|
38
|
-
// is supposed to be the recommended way:
|
|
39
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#use_texstorage_to_create_textures
|
|
40
|
-
const inputFrameTexture = gl.createTexture();
|
|
41
|
-
gl.bindTexture(gl.TEXTURE_2D, inputFrameTexture);
|
|
42
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
43
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
44
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
45
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
46
|
-
// TODO Rename segmentation and person mask to be more specific
|
|
47
|
-
const segmentationTexture = createTexture(gl, gl.RGBA8, segmentationWidth, segmentationHeight);
|
|
48
|
-
const personMaskTexture = createTexture(gl, gl.RGBA8, frameWidth, frameHeight);
|
|
49
|
-
const resizingStage = buildResizingStage(gl, vertexShader, positionBuffer, texCoordBuffer, tflite, segmentationConfig);
|
|
50
|
-
const loadSegmentationStage = buildSoftmaxStage(gl, vertexShader, positionBuffer, texCoordBuffer, tflite, segmentationTexture, segmentationConfig);
|
|
51
|
-
const jointBilateralFilterStage = buildJointBilateralFilterStage(gl, vertexShader, positionBuffer, texCoordBuffer, segmentationTexture, personMaskTexture, canvas, segmentationConfig);
|
|
52
|
-
const backgroundStage = backgroundFilter === 'blur'
|
|
53
|
-
? buildBackgroundBlurStage(gl, vertexShader, positionBuffer, texCoordBuffer, personMaskTexture, canvas, blurLevel || 'high')
|
|
54
|
-
: buildBackgroundImageStage(gl, positionBuffer, texCoordBuffer, personMaskTexture, backgroundImage, canvas);
|
|
55
|
-
function render() {
|
|
56
|
-
gl.activeTexture(gl.TEXTURE0);
|
|
57
|
-
gl.bindTexture(gl.TEXTURE_2D, inputFrameTexture);
|
|
58
|
-
// texImage2D seems faster than texSubImage2D to upload
|
|
59
|
-
// video texture
|
|
60
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, videoSource);
|
|
61
|
-
gl.bindVertexArray(vertexArray);
|
|
62
|
-
resizingStage.render();
|
|
63
|
-
tflite._runInference();
|
|
64
|
-
loadSegmentationStage.render();
|
|
65
|
-
jointBilateralFilterStage.render();
|
|
66
|
-
backgroundStage.render();
|
|
67
|
-
}
|
|
68
|
-
function updatePostProcessingConfig() {
|
|
69
|
-
jointBilateralFilterStage.updateSigmaSpace(1);
|
|
70
|
-
jointBilateralFilterStage.updateSigmaColor(0.1);
|
|
71
|
-
if (backgroundFilter === 'image') {
|
|
72
|
-
const backgroundImageStage = backgroundStage;
|
|
73
|
-
backgroundImageStage.updateCoverage([0.5, 0.75]);
|
|
74
|
-
backgroundImageStage.updateLightWrapping(0.3);
|
|
75
|
-
backgroundImageStage.updateBlendMode('screen');
|
|
76
|
-
}
|
|
77
|
-
else if (backgroundFilter === 'blur') {
|
|
78
|
-
const backgroundBlurStage = backgroundStage;
|
|
79
|
-
backgroundBlurStage.updateCoverage([0.5, 0.75]);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
// TODO Handle no background in a separate pipeline path
|
|
83
|
-
const backgroundImageStage = backgroundStage;
|
|
84
|
-
backgroundImageStage.updateCoverage([0, 0.9999]);
|
|
85
|
-
backgroundImageStage.updateLightWrapping(0);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
function cleanUp() {
|
|
89
|
-
backgroundStage.cleanUp();
|
|
90
|
-
jointBilateralFilterStage.cleanUp();
|
|
91
|
-
loadSegmentationStage.cleanUp();
|
|
92
|
-
resizingStage.cleanUp();
|
|
93
|
-
gl.deleteTexture(personMaskTexture);
|
|
94
|
-
gl.deleteTexture(segmentationTexture);
|
|
95
|
-
gl.deleteTexture(inputFrameTexture);
|
|
96
|
-
gl.deleteBuffer(texCoordBuffer);
|
|
97
|
-
gl.deleteBuffer(positionBuffer);
|
|
98
|
-
gl.deleteVertexArray(vertexArray);
|
|
99
|
-
gl.deleteShader(vertexShader);
|
|
100
|
-
}
|
|
101
|
-
return { render, updatePostProcessingConfig, cleanUp };
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export { buildWebGL2Pipeline };
|
|
105
|
-
//# sourceMappingURL=webgl2Pipeline.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webgl2Pipeline.js","sources":["../../../../../../../src/legacy/webgl2/webgl2Pipeline.ts"],"sourcesContent":["import { TFLite } from '../tflite';\nimport { compileShader, createTexture, glsl } from '../helpers/webglHelper';\nimport {\n BackgroundBlurStage,\n buildBackgroundBlurStage,\n} from './backgroundBlurStage';\nimport {\n BackgroundImageStage,\n buildBackgroundImageStage,\n} from './backgroundImageStage';\nimport { buildJointBilateralFilterStage } from './jointBilateralFilterStage';\nimport { buildResizingStage } from './resizingStage';\nimport { buildSoftmaxStage } from './softmaxStage';\nimport { SegmentationParams } from '../segmentation';\nimport type { BackgroundBlurLevel, BackgroundFilter } from '../../types';\n\nexport function buildWebGL2Pipeline(\n videoSource: HTMLVideoElement,\n backgroundImage: HTMLImageElement | undefined,\n blurLevel: BackgroundBlurLevel | undefined,\n backgroundFilter: BackgroundFilter,\n canvas: HTMLCanvasElement,\n tflite: TFLite,\n segmentationConfig: SegmentationParams,\n onError?: (error: any) => void,\n) {\n const gl = canvas.getContext('webgl2')!;\n if (!gl) throw new Error('WebGL2 is not supported');\n if (gl.isContextLost()) throw new Error('WebGL2 context was lost');\n\n const { width: frameWidth, height: frameHeight } = videoSource;\n const { width: segmentationWidth, height: segmentationHeight } =\n segmentationConfig;\n\n const vertexShaderSource = glsl`#version 300 es\n\n in vec2 a_position;\n in vec2 a_texCoord;\n out vec2 v_texCoord;\n\n void main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n v_texCoord = a_texCoord;\n }\n `;\n const vertexShader = compileShader(gl, gl.VERTEX_SHADER, vertexShaderSource);\n\n const vertexArray = gl.createVertexArray();\n gl.bindVertexArray(vertexArray);\n\n const positionBuffer = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0]),\n gl.STATIC_DRAW,\n );\n\n const texCoordBuffer = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0]),\n gl.STATIC_DRAW,\n );\n\n // We don't use texStorage2D here because texImage2D seems faster\n // to upload video texture than texSubImage2D even though the latter\n // is supposed to be the recommended way:\n // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#use_texstorage_to_create_textures\n const inputFrameTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, inputFrameTexture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n\n // TODO Rename segmentation and person mask to be more specific\n const segmentationTexture = createTexture(\n gl,\n gl.RGBA8,\n segmentationWidth,\n segmentationHeight,\n )!;\n const personMaskTexture = createTexture(\n gl,\n gl.RGBA8,\n frameWidth,\n frameHeight,\n )!;\n\n const resizingStage = buildResizingStage(\n gl,\n vertexShader,\n positionBuffer,\n texCoordBuffer,\n tflite,\n segmentationConfig,\n onError,\n );\n const loadSegmentationStage = buildSoftmaxStage(\n gl,\n vertexShader,\n positionBuffer,\n texCoordBuffer,\n tflite,\n segmentationTexture,\n segmentationConfig,\n );\n\n const jointBilateralFilterStage = buildJointBilateralFilterStage(\n gl,\n vertexShader,\n positionBuffer,\n texCoordBuffer,\n segmentationTexture,\n personMaskTexture,\n canvas,\n segmentationConfig,\n );\n const backgroundStage =\n backgroundFilter === 'blur'\n ? buildBackgroundBlurStage(\n gl,\n vertexShader,\n positionBuffer,\n texCoordBuffer,\n personMaskTexture,\n canvas,\n blurLevel || 'high',\n )\n : buildBackgroundImageStage(\n gl,\n positionBuffer,\n texCoordBuffer,\n personMaskTexture,\n backgroundImage,\n canvas,\n );\n\n function render() {\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, inputFrameTexture);\n\n // texImage2D seems faster than texSubImage2D to upload\n // video texture\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n videoSource,\n );\n\n gl.bindVertexArray(vertexArray);\n\n resizingStage.render();\n\n tflite._runInference();\n\n loadSegmentationStage.render();\n jointBilateralFilterStage.render();\n backgroundStage.render();\n }\n\n function updatePostProcessingConfig() {\n jointBilateralFilterStage.updateSigmaSpace(1);\n jointBilateralFilterStage.updateSigmaColor(0.1);\n\n if (backgroundFilter === 'image') {\n const backgroundImageStage = backgroundStage as BackgroundImageStage;\n backgroundImageStage.updateCoverage([0.5, 0.75]);\n backgroundImageStage.updateLightWrapping(0.3);\n backgroundImageStage.updateBlendMode('screen');\n } else if (backgroundFilter === 'blur') {\n const backgroundBlurStage = backgroundStage as BackgroundBlurStage;\n backgroundBlurStage.updateCoverage([0.5, 0.75]);\n } else {\n // TODO Handle no background in a separate pipeline path\n const backgroundImageStage = backgroundStage as BackgroundImageStage;\n backgroundImageStage.updateCoverage([0, 0.9999]);\n backgroundImageStage.updateLightWrapping(0);\n }\n }\n\n function cleanUp() {\n backgroundStage.cleanUp();\n jointBilateralFilterStage.cleanUp();\n loadSegmentationStage.cleanUp();\n resizingStage.cleanUp();\n\n gl.deleteTexture(personMaskTexture);\n gl.deleteTexture(segmentationTexture);\n gl.deleteTexture(inputFrameTexture);\n gl.deleteBuffer(texCoordBuffer);\n gl.deleteBuffer(positionBuffer);\n gl.deleteVertexArray(vertexArray);\n gl.deleteShader(vertexShader);\n }\n\n return { render, updatePostProcessingConfig, cleanUp };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { TFLite } from './tflite';
|
|
2
|
-
import { SegmentationLevel } from './segmentation';
|
|
3
|
-
import { BackgroundBlurLevel, BackgroundFilter } from '../types';
|
|
4
|
-
export type Renderer = {
|
|
5
|
-
/**
|
|
6
|
-
* Disposes of the renderer.
|
|
7
|
-
*/
|
|
8
|
-
dispose: () => void;
|
|
9
|
-
};
|
|
10
|
-
export declare function createRenderer(tflite: TFLite, videoSource: HTMLVideoElement, targetCanvas: HTMLCanvasElement, options: {
|
|
11
|
-
backgroundFilter: BackgroundFilter;
|
|
12
|
-
segmentationLevel?: SegmentationLevel;
|
|
13
|
-
backgroundImage?: HTMLImageElement;
|
|
14
|
-
backgroundBlurLevel?: BackgroundBlurLevel;
|
|
15
|
-
fps?: number;
|
|
16
|
-
}, onError?: (error: any) => void): Renderer;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Use it along with boyswan.glsl-literal VSCode extension
|
|
3
|
-
* to get GLSL syntax highlighting.
|
|
4
|
-
* https://marketplace.visualstudio.com/items?itemName=boyswan.glsl-literal
|
|
5
|
-
*
|
|
6
|
-
* On VSCode OSS, boyswan.glsl-literal requires slevesque.shader extension
|
|
7
|
-
* to be installed as well.
|
|
8
|
-
* https://marketplace.visualstudio.com/items?itemName=slevesque.shader
|
|
9
|
-
*/
|
|
10
|
-
export declare const glsl: (template: {
|
|
11
|
-
raw: readonly string[] | ArrayLike<string>;
|
|
12
|
-
}, ...substitutions: any[]) => string;
|
|
13
|
-
export declare function createPipelineStageProgram(gl: WebGL2RenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader, positionBuffer: WebGLBuffer, texCoordBuffer: WebGLBuffer): WebGLProgram;
|
|
14
|
-
export declare function createProgram(gl: WebGL2RenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader): WebGLProgram;
|
|
15
|
-
export declare function compileShader(gl: WebGL2RenderingContext, shaderType: number, shaderSource: string): WebGLShader;
|
|
16
|
-
export declare function createTexture(gl: WebGL2RenderingContext, internalformat: number, width: number, height: number, minFilter?: 9728, magFilter?: 9728): WebGLTexture;
|
|
17
|
-
export declare function readPixelsAsync(gl: WebGL2RenderingContext, x: number, y: number, width: number, height: number, format: number, type: number, dest: ArrayBufferView): Promise<ArrayBufferView<ArrayBufferLike>>;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export interface TFLite extends EmscriptenModule {
|
|
2
|
-
_getModelBufferMemoryOffset(): number;
|
|
3
|
-
_getInputMemoryOffset(): number;
|
|
4
|
-
_getInputHeight(): number;
|
|
5
|
-
_getInputWidth(): number;
|
|
6
|
-
_getInputChannelCount(): number;
|
|
7
|
-
_getOutputMemoryOffset(): number;
|
|
8
|
-
_getOutputHeight(): number;
|
|
9
|
-
_getOutputWidth(): number;
|
|
10
|
-
_getOutputChannelCount(): number;
|
|
11
|
-
_loadModel(bufferSize: number): number;
|
|
12
|
-
_runInference(): number;
|
|
13
|
-
}
|
|
14
|
-
export declare const loadTFLite: (options?: {
|
|
15
|
-
basePath?: string;
|
|
16
|
-
tfFilePath?: string;
|
|
17
|
-
modelFilePath?: string;
|
|
18
|
-
}) => Promise<TFLite>;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { BackgroundBlurLevel } from '../../types';
|
|
2
|
-
export type BackgroundBlurStage = {
|
|
3
|
-
render(): void;
|
|
4
|
-
updateCoverage(coverage: [number, number]): void;
|
|
5
|
-
cleanUp(): void;
|
|
6
|
-
};
|
|
7
|
-
export declare function buildBackgroundBlurStage(gl: WebGL2RenderingContext, vertexShader: WebGLShader, positionBuffer: WebGLBuffer, texCoordBuffer: WebGLBuffer, personMaskTexture: WebGLTexture, canvas: HTMLCanvasElement, blurLevel: BackgroundBlurLevel): BackgroundBlurStage;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export type BackgroundImageStage = {
|
|
2
|
-
render(): void;
|
|
3
|
-
updateCoverage(coverage: [number, number]): void;
|
|
4
|
-
updateLightWrapping(lightWrapping: number): void;
|
|
5
|
-
updateBlendMode(blendMode: 'screen' | 'linearDodge'): void;
|
|
6
|
-
cleanUp(): void;
|
|
7
|
-
};
|
|
8
|
-
export declare function buildBackgroundImageStage(gl: WebGL2RenderingContext, positionBuffer: WebGLBuffer, texCoordBuffer: WebGLBuffer, personMaskTexture: WebGLTexture, backgroundImage: HTMLImageElement | undefined, canvas: HTMLCanvasElement): BackgroundImageStage;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { SegmentationParams } from '../segmentation';
|
|
2
|
-
export declare function buildJointBilateralFilterStage(gl: WebGL2RenderingContext, vertexShader: WebGLShader, positionBuffer: WebGLBuffer, texCoordBuffer: WebGLBuffer, inputTexture: WebGLTexture, outputTexture: WebGLTexture, canvas: HTMLCanvasElement, segmentationConfig: SegmentationParams): {
|
|
3
|
-
render: () => void;
|
|
4
|
-
updateSigmaSpace: (sigmaSpace: number) => void;
|
|
5
|
-
updateSigmaColor: (sigmaColor: number) => void;
|
|
6
|
-
cleanUp: () => void;
|
|
7
|
-
};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { TFLite } from '../tflite';
|
|
2
|
-
import { SegmentationParams } from '../segmentation';
|
|
3
|
-
export declare function buildResizingStage(gl: WebGL2RenderingContext, vertexShader: WebGLShader, positionBuffer: WebGLBuffer, texCoordBuffer: WebGLBuffer, tflite: TFLite, segmentationConfig: SegmentationParams, onError?: (error: any) => void): {
|
|
4
|
-
render: () => void;
|
|
5
|
-
cleanUp: () => void;
|
|
6
|
-
};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { TFLite } from '../tflite';
|
|
2
|
-
import { SegmentationParams } from '../segmentation';
|
|
3
|
-
export declare function buildSoftmaxStage(gl: WebGL2RenderingContext, vertexShader: WebGLShader, positionBuffer: WebGLBuffer, texCoordBuffer: WebGLBuffer, tflite: TFLite, outputTexture: WebGLTexture, segmentationConfig: SegmentationParams): {
|
|
4
|
-
render: () => void;
|
|
5
|
-
cleanUp: () => void;
|
|
6
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { TFLite } from '../tflite';
|
|
2
|
-
import { SegmentationParams } from '../segmentation';
|
|
3
|
-
import type { BackgroundBlurLevel, BackgroundFilter } from '../../types';
|
|
4
|
-
export declare function buildWebGL2Pipeline(videoSource: HTMLVideoElement, backgroundImage: HTMLImageElement | undefined, blurLevel: BackgroundBlurLevel | undefined, backgroundFilter: BackgroundFilter, canvas: HTMLCanvasElement, tflite: TFLite, segmentationConfig: SegmentationParams, onError?: (error: any) => void): {
|
|
5
|
-
render: () => void;
|
|
6
|
-
updatePostProcessingConfig: () => void;
|
|
7
|
-
cleanUp: () => void;
|
|
8
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { WorkerTimer } from '@stream-io/worker-timer';
|
|
2
|
-
import { TFLite } from './tflite';
|
|
3
|
-
import { buildWebGL2Pipeline } from './webgl2/webgl2Pipeline';
|
|
4
|
-
import { getSegmentationParams, SegmentationLevel } from './segmentation';
|
|
5
|
-
import { BackgroundBlurLevel, BackgroundFilter } from '../types';
|
|
6
|
-
|
|
7
|
-
export type Renderer = {
|
|
8
|
-
/**
|
|
9
|
-
* Disposes of the renderer.
|
|
10
|
-
*/
|
|
11
|
-
dispose: () => void;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export function createRenderer(
|
|
15
|
-
tflite: TFLite,
|
|
16
|
-
videoSource: HTMLVideoElement,
|
|
17
|
-
targetCanvas: HTMLCanvasElement,
|
|
18
|
-
options: {
|
|
19
|
-
backgroundFilter: BackgroundFilter;
|
|
20
|
-
segmentationLevel?: SegmentationLevel;
|
|
21
|
-
backgroundImage?: HTMLImageElement;
|
|
22
|
-
backgroundBlurLevel?: BackgroundBlurLevel;
|
|
23
|
-
fps?: number;
|
|
24
|
-
},
|
|
25
|
-
onError?: (error: any) => void,
|
|
26
|
-
): Renderer {
|
|
27
|
-
const {
|
|
28
|
-
backgroundFilter,
|
|
29
|
-
backgroundImage,
|
|
30
|
-
backgroundBlurLevel,
|
|
31
|
-
segmentationLevel = SegmentationLevel.HIGH,
|
|
32
|
-
fps = 30,
|
|
33
|
-
} = options;
|
|
34
|
-
if (backgroundFilter === 'image' && !backgroundImage) {
|
|
35
|
-
throw new Error(
|
|
36
|
-
`backgroundImage element is required when backgroundFilter is image`,
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const pipeline = buildWebGL2Pipeline(
|
|
41
|
-
videoSource,
|
|
42
|
-
backgroundImage,
|
|
43
|
-
backgroundBlurLevel,
|
|
44
|
-
backgroundFilter,
|
|
45
|
-
targetCanvas,
|
|
46
|
-
tflite,
|
|
47
|
-
getSegmentationParams(segmentationLevel),
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
const timers = new WorkerTimer({ useWorker: true });
|
|
51
|
-
const id = timers.setInterval(
|
|
52
|
-
() => {
|
|
53
|
-
try {
|
|
54
|
-
pipeline.render();
|
|
55
|
-
|
|
56
|
-
if (backgroundFilter === 'image') {
|
|
57
|
-
pipeline.updatePostProcessingConfig();
|
|
58
|
-
}
|
|
59
|
-
} catch (error) {
|
|
60
|
-
onError?.(error);
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
Math.floor(1000 / (fps <= 0 ? 30 : fps)),
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
dispose: () => {
|
|
68
|
-
pipeline.cleanUp();
|
|
69
|
-
timers.clearInterval(id);
|
|
70
|
-
timers.destroy();
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
}
|