0

有一些方法可以使用tensorflow.jsbody-pix模型从浏览器本身的网络摄像头输入中删除背景。使用这些在互联网上给出了许多示例代码,但这些示例效果不佳,结果非常滞后且不够准确,无法用于生产。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Background Removal</title>
    <!-- Load TensorFlow.js -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.2"></script>
    <!-- Load BodyPix -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/body-pix@2.0"></script>
</head>

<body>
    <h1>Background Removal w/ BodyPix</h1>
    <div class="container parent">
        <div class="video box">
            <video id="video" autoplay width="640px" height="480px">

            </video>
        </div>
        <div class="removed box">
            <canvas id="canvas" autoplay width="640px" height="480px">

            </canvas>
        </div>
    </div>
    
    <script defer src="main.js"></script>
</body>

</html>

main.js

// ! Source to stream from
const video = document.getElementById('video');
// ! Destination to stream to
const canvas = document.getElementById('canvas');
// ! Video Streaming using getUserMedia
if (navigator.mediaDevices) {
    navigator.mediaDevices
        .getUserMedia({ video: { facingMode: "environment" } })
        .then(stream => {
            video.srcObject = stream;
            video.play();
            setInterval(removeBg, 100); // * Call the segmenting fu
            // removeBg();
        });
}
// ! Loading bodyPix

async function removeBg() {
    //  ? Loading BodyPix w/ various parameters
    const net = await bodyPix.load({
        architecture: 'MobileNetV1',
        outputStride: 16,
        multiplier: 0.75,
        quantBytes: 2
    });

    // ? Segmentation occurs here, taking video frames as the input
    const segmentation = await net.segmentPerson(video, {
        flipHorizontal: false,
        internalResolution: 'medium',
        segmentationThreshold: 0.5
    });

    // Convert the segmentation into a mask to darken the background.
    const foregroundColor = { r: 0, g: 0, b: 0, a: 255 };
    const backgroundColor = { r: 0, g: 0, b: 0, a: 0 };
    const backgroundDarkeningMask = bodyPix.toMask(segmentation, foregroundColor, backgroundColor, false);

    // const opacity = 0.7;
    // const maskBlurAmount = 3;
    // const flipHorizontal = false;
    compositeFrame(backgroundDarkeningMask);
    // requestAnimationFrame(removeBg);
    // bodyPix.drawMask(canvas, video, backgroundDarkeningMask, opacity, maskBlurAmount, flipHorizontal);
}
async function compositeFrame(backgroundDarkeningMask) {
    if (!backgroundDarkeningMask) return;
    // grab canvas holding the bg image
    var ctx = canvas.getContext('2d');
    // composite the segmentation mask on top
    ctx.globalCompositeOperation = 'destination-over';
    ctx.putImageData(backgroundDarkeningMask, 0, 0);
    // composite the video frame
    ctx.globalCompositeOperation = 'source-in';
    ctx.drawImage(video, 0, 0, 640, 480);
}

有没有办法改进这种工作方式或新方式以在浏览器本身中准确流畅地删除背景?

4

1 回答 1

1

使用 Mediapipe SelfieSegmentation

于 2021-08-12T06:10:12.587 回答