有一些方法可以使用tensorflow.js和body-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);
}
有没有办法改进这种工作方式或新方式以在浏览器本身中准确流畅地删除背景?