Bodypix (People Segmentation & Keypoints)

Model Homepage

body-pix
Try the live demo here!

800800

Video Example People Walking

Video Example Basketball Sports

Examples

362362 316316

Performance

  • Image resolution <1920x1080
  • First run (loading model) may be 10x slower then ongoing runs
  • Lower values for epsilon_modifer will give more polygon points (slower run, may be harder to edit). Higher values will give less points, but if the value is too high the polygon won't be accurate.

In Diffgram

Search: bodypix

NPM Packages

https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js
https://cdn.jsdelivr.net/npm/@tensorflow-models/[email protected]
https://docs.opencv.org/master/opencv.js

Code

if (!this.bodypix_model) {
  this.bodypix_model = await bodyPix.load(
        {  architecture: 'ResNet50',
            outputStride: 32,
            quantBytes: 4});
} else {
    console.log("used cached model")
}

let epsilon_modifer =  0.001 

var warm_up = await this.bodypix_model.segmentPerson(
  diffgram.get_new_canvas(), {
  }); 

let canvas = diffgram.get_new_canvas()
let metadata = diffgram.get_metadata()

var segmentation
segmentation = await this.bodypix_model.segmentPerson(canvas, {
  internalResolution: "full",
  maxDetections: 30
}); 

const cv_formatted_mat = new cv.matFromArray(
  metadata.height,
 metadata.width,
  cv.CV_8UC1, segmentation.data);

var contours = new cv.MatVector()
const hierarchy = new cv.Mat()

cv.findContours(
  cv_formatted_mat, 
  contours, hierarchy, cv.RETR_CCOMP, cv.CHAIN_APPROX_SIMPLE)

for (let i = 0; i < contours.size(); i++) {
  let contour = contours.get(i)
  let perimeter = cv.arcLength(contour, true);
  let epsilon = epsilon_modifer * cv.arcLength(contour,true)
  
  let tmp = new cv.Mat();
  cv.approxPolyDP(contour, tmp, epsilon, true);
  polypoints = tmp.data32S
  
  let points_list = []
  for (let i = 0; i < polypoints.length; i++) {
    if (i % 2 != 0) {continue}
    let x = polypoints[i]
    let y = polypoints[i + 1]
    points_list.push({'x' : x, 'y' : y})
  }
  diffgram.create_polygon(points_list)
  
}