Real-time person and body part segmentation using TensorFlow.js for web browsers with machine learning models.
—
Visual rendering utilities for creating masks, overlays, and special effects from segmentation results. Provides functions for background blur, body part blur, mask generation, and custom visualization effects.
Create binary and colored masks from segmentation results.
/**
* Creates a binary mask image from segmentation results
* @param segmentation - Segmentation result (person or part segmentation)
* @param foreground - Foreground color (default: transparent)
* @param background - Background color (default: opaque black)
* @param drawContour - Draw contour lines around segments
* @param foregroundIds - Which part IDs are considered foreground
* @returns ImageData containing the mask
*/
function toMask(
segmentation: SemanticPersonSegmentation | SemanticPartSegmentation | PersonSegmentation[] | PartSegmentation[],
foreground?: Color,
background?: Color,
drawContour?: boolean,
foregroundIds?: number[]
): ImageData;
/**
* Creates colored visualization of body part segmentation
* @param partSegmentation - Part segmentation result
* @param partColors - RGB colors for each part (default: rainbow colors)
* @returns ImageData with colored parts
*/
function toColoredPartMask(
partSegmentation: SemanticPartSegmentation | PartSegmentation[],
partColors?: Array<[number, number, number]>
): ImageData;
interface Color {
r: number; // Red (0-255)
g: number; // Green (0-255)
b: number; // Blue (0-255)
a: number; // Alpha (0-255)
}Create background blur and bokeh effects for virtual backgrounds.
/**
* Creates bokeh/background blur effect while keeping people in focus
* @param canvas - Target canvas for rendering
* @param image - Source image/video element
* @param personSegmentation - Person segmentation result
* @param backgroundBlurAmount - Background blur intensity (1-20)
* @param edgeBlurAmount - Edge smoothing blur (0-20)
* @param flipHorizontal - Flip result horizontally
*/
function drawBokehEffect(
canvas: HTMLCanvasElement | OffscreenCanvas,
image: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement,
personSegmentation: SemanticPersonSegmentation | PersonSegmentation[],
backgroundBlurAmount?: number,
edgeBlurAmount?: number,
flipHorizontal?: boolean
): void;
/**
* Draws image with mask overlay on canvas
* @param canvas - Target canvas for rendering
* @param image - Source image/video element
* @param maskImage - Mask to overlay (from toMask function)
* @param maskOpacity - Mask opacity (0-1)
* @param maskBlurAmount - Blur radius for mask edges (0-20)
* @param flipHorizontal - Flip result horizontally
*/
function drawMask(
canvas: HTMLCanvasElement | OffscreenCanvas,
image: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement,
maskImage: ImageData | null,
maskOpacity?: number,
maskBlurAmount?: number,
flipHorizontal?: boolean
): void;
/**
* Draws image with pixelated mask effect
* @param canvas - Target canvas for rendering
* @param image - Source image/video element
* @param maskImage - Mask to overlay
* @param maskOpacity - Mask opacity (0-1)
* @param maskBlurAmount - Blur radius for mask edges (0-20)
* @param flipHorizontal - Flip result horizontally
* @param pixelCellWidth - Pixel cell size for pixelation effect
*/
function drawPixelatedMask(
canvas: HTMLCanvasElement | OffscreenCanvas,
image: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement,
maskImage: ImageData,
maskOpacity?: number,
maskBlurAmount?: number,
flipHorizontal?: boolean,
pixelCellWidth?: number
): void;Target specific body parts for privacy or creative effects.
/**
* Blurs specific body parts (e.g., faces for privacy)
* @param canvas - Target canvas for rendering
* @param image - Source image/video element
* @param partSegmentation - Part segmentation result
* @param bodyPartIdsToBlur - Array of part IDs to blur (default: [0,1] for faces)
* @param backgroundBlurAmount - Blur intensity (1-20)
* @param edgeBlurAmount - Edge smoothing blur (0-20)
* @param flipHorizontal - Flip result horizontally
*/
function blurBodyPart(
canvas: HTMLCanvasElement | OffscreenCanvas,
image: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement,
partSegmentation: SemanticPartSegmentation | PartSegmentation[],
bodyPartIdsToBlur?: number[],
backgroundBlurAmount?: number,
edgeBlurAmount?: number,
flipHorizontal?: boolean
): void;import * as bodyPix from '@tensorflow-models/body-pix';
const net = await bodyPix.load();
const video = document.getElementById('webcam');
const canvas = document.getElementById('output');
// Create background blur effect
const segmentation = await net.segmentPerson(video);
bodyPix.drawBokehEffect(canvas, video, segmentation, 7, 3, true);// Create custom colored mask
const segmentation = await net.segmentPerson(imageElement);
const greenScreenMask = bodyPix.toMask(segmentation,
{ r: 0, g: 255, b: 0, a: 255 }, // Green foreground
{ r: 255, g: 0, b: 255, a: 255 } // Magenta background
);
// Apply mask with custom styling
bodyPix.drawMask(canvas, imageElement, greenScreenMask, 0.8, 2);// Blur faces for privacy
const partSegmentation = await net.segmentPersonParts(imageElement);
const FACE_PARTS = [0, 1]; // left_face, right_face
bodyPix.blurBodyPart(canvas, imageElement, partSegmentation, FACE_PARTS, 15, 3);// Create rainbow-colored body part visualization
const partSegmentation = await net.segmentPersonParts(imageElement);
const coloredParts = bodyPix.toColoredPartMask(partSegmentation);
// Display on canvas
const ctx = canvas.getContext('2d');
ctx.putImageData(coloredParts, 0, 0);
// Create hand-only highlight
const HAND_PARTS = [10, 11];
const handMask = bodyPix.toMask(partSegmentation,
{ r: 255, g: 255, b: 0, a: 200 }, // Semi-transparent yellow
{ r: 0, g: 0, b: 0, a: 0 }, // Transparent background
false,
HAND_PARTS
);
bodyPix.drawMask(canvas, imageElement, handMask, 0.7);async function applyVideoEffect() {
const video = document.getElementById('webcam');
const canvas = document.getElementById('output');
// Resize canvas to match video
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
const segmentation = await net.segmentPerson(video, {
internalResolution: 'medium',
segmentationThreshold: 0.7
});
// Apply different effects based on user selection
const effectType = document.getElementById('effect-select').value;
switch (effectType) {
case 'blur':
bodyPix.drawBokehEffect(canvas, video, segmentation, 10, 5, true);
break;
case 'mask':
const mask = bodyPix.toMask(segmentation);
bodyPix.drawMask(canvas, video, mask, 0.8);
break;
case 'pixelate':
const pixelMask = bodyPix.toMask(segmentation);
bodyPix.drawPixelatedMask(canvas, video, pixelMask, 1.0, 0, true, 8);
break;
}
// Continue for next frame
requestAnimationFrame(applyVideoEffect);
}// Create gradient mask effect
function createGradientMask(segmentation: SemanticPersonSegmentation): ImageData {
const { data, width, height } = segmentation;
const maskData = new Uint8ClampedArray(width * height * 4);
for (let i = 0; i < data.length; i++) {
const isPerson = data[i] === 1;
const x = i % width;
const y = Math.floor(i / width);
if (isPerson) {
// Create gradient based on position
const gradientIntensity = x / width;
maskData[i * 4] = Math.floor(255 * gradientIntensity); // R
maskData[i * 4 + 1] = Math.floor(255 * (1 - gradientIntensity)); // G
maskData[i * 4 + 2] = 128; // B
maskData[i * 4 + 3] = 255; // A
} else {
// Transparent background
maskData[i * 4 + 3] = 0;
}
}
return new ImageData(maskData, width, height);
}
const segmentation = await net.segmentPerson(imageElement);
const gradientMask = createGradientMask(segmentation);
bodyPix.drawMask(canvas, imageElement, gradientMask, 0.8);Install with Tessl CLI
npx tessl i tessl/npm-tensorflow-models--body-pix