()
| 34 | let inputTextureFrameBuffer = createTextureFrameBuffer(gl, gl.LINEAR, videoWidth, videoHeight); |
| 35 | |
| 36 | const predict = async () => { |
| 37 | beginEstimateSegmentationStats(); |
| 38 | |
| 39 | // Put original video content on the input texture. |
| 40 | inputTextureFrameBuffer.bindTexture(); |
| 41 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB8, gl.RGB, gl.UNSIGNED_BYTE, video); |
| 42 | |
| 43 | // Run segmentation model inference. |
| 44 | const segmentationConfig = {flipHorizontal: false, multiSegmentation: false, segmentBodyParts: true, |
| 45 | segmentationThreshold: 0.5}; |
| 46 | segmentation = await model.segmentPeople(video, segmentationConfig); |
| 47 | |
| 48 | // Get the tensor result and the texture that holds the data. |
| 49 | // We tell the system to use the video width and height as the tex shape, |
| 50 | // this allows the densely packed data to have the same layout as the |
| 51 | // original video content, which simplifies the shader logic. This only |
| 52 | // works if the data shape is [1, height, width, 4]. |
| 53 | const tensor = await segmentation[0].mask.toTensor(); |
| 54 | const data = |
| 55 | tensor.dataToGPU({customTexShape: [videoHeight, videoWidth]}); |
| 56 | |
| 57 | // Combine the input texture and tensor texture with additional shader logic. |
| 58 | // In this case, we just pass through foreground pixels and make background |
| 59 | // pixels more transparent. |
| 60 | const result = applyMask.process(inputTextureFrameBuffer, createTexture( |
| 61 | gl, data.texture, videoWidth, videoHeight)); |
| 62 | |
| 63 | // Other processing steps can go here. |
| 64 | |
| 65 | // Once we're done with all the processing, we can draw the texture on the canvas. |
| 66 | |
| 67 | // Making gl.DRAW_FRAMEBUFFER to be null sets rendering back to default framebuffer. |
| 68 | gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); |
| 69 | // Caching the data of the result texture to be drawn in the gl.READ_FRAMEBUFFER. |
| 70 | gl.bindFramebuffer(gl.READ_FRAMEBUFFER, result.framebuffer_); |
| 71 | // Transfer the data from read framebuffer to the default framebuffer to make it show |
| 72 | // on canvas. |
| 73 | gl.blitFramebuffer( |
| 74 | 0, 0, videoWidth, videoHeight, 0, videoHeight, videoWidth, 0, gl.COLOR_BUFFER_BIT, |
| 75 | gl.LINEAR); |
| 76 | |
| 77 | // Make sure to dispose all tensors, otherwise there will be memory leak. |
| 78 | tensor.dispose(); |
| 79 | data.tensorRef.dispose(); |
| 80 | endEstimateSegmentationStats(); |
| 81 | |
| 82 | requestAnimationFrame(predict); |
| 83 | }; |
| 84 | |
| 85 | predict(); |
| 86 | } |
no test coverage detected