This demo segments and displays the foreground person from WebCam images on a website using Google MediaPipe/selfie_segmentation.js.
Display the Person Filled in Blue
After granting camera access, the video feed will appear shortly.
Please position a person within the camera view.
Only the person will be filled in blue, while the background remains unchanged.
Source code
<!DOCTYPE html>
<html lang="ja">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0,user-scalable=yes">
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/control_utils/control_utils.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils/drawing_utils.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation@0.1/selfie_segmentation.js" crossorigin="anonymous"></script>
<script type="module">
let video, can, ctx;
window.addEventListener('load', async function(event){
video = document.querySelector('.video');
can = document.querySelector('.can');
ctx = can.getContext('2d');
const selfieSegmentation = new SelfieSegmentation({
locateFile: function(file){
return `https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation@0.1/${file}`;
}
});
selfieSegmentation.setOptions({
// 0: Use the general model, 1: Use the landscape model
modelSelection: 1,
});
selfieSegmentation.onResults(onResults);
const camera = new Camera(video, {
onFrame: async function(){
await selfieSegmentation.send({image: video});
},
width: 640,
height: 480
});
camera.start();
});
function onResults(results) {
ctx.save();
// Draw new shapes on top of the existing canvas content (default)
ctx.globalCompositeOperation = 'source-over';
// Clear the canvas with transparent black
ctx.clearRect(0, 0, can.width, can.height);
// Draw the person segmentation mask
ctx.drawImage(results.segmentationMask, 0, 0, can.width, can.height);
// Draw only the overlapping area between the new shape and the canvas;
// this allows filling only the non‑transparent regions
ctx.globalCompositeOperation = 'source-in';
ctx.fillStyle = '#00F';
ctx.fillRect(0, 0, can.width, can.height);
// Draw only where the current image overlaps; transparent areas remain untouched
ctx.globalCompositeOperation = 'destination-atop';
ctx.drawImage(results.image, 0, 0, can.width, can.height);
ctx.restore();
}
</script>
</head>
<body>
<div class="container">
<video class="video" style="display:none;"></video>
<canvas class="can" width="640" height="480" style="transform:scale(-1,1);width:90%;max-width:640px;height:auto;"></canvas>
</div>
</body>
</html>
Display Only the Person and Fill the Background with Black
To do the opposite of the previous example—show only the person and fill the background with black—rewrite the onResults function as follows.
function onResults(results) {
ctx.save();
// Draw new shapes on top of the existing canvas content (default)
ctx.globalCompositeOperation = 'source-over';
// Clear the canvas with transparent black
ctx.clearRect(0, 0, can.width, can.height);
// Draw the person segmentation mask
ctx.drawImage(results.segmentationMask, 0, 0, can.width, can.height);
// Draw only the non‑transparent areas
ctx.globalCompositeOperation = 'source-atop';
ctx.drawImage(results.image, 0, 0, can.width, can.height);
// Draw only where the current image overlaps; transparent areas remain untouched
// In other words, this fills only the transparent regions
ctx.globalCompositeOperation = 'destination-atop';
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, can.width, can.height);
ctx.restore();
}

