function detectPoseInRealTime(video) {
  const canvas = document.getElementById('output');
  const keypointCanvas = document.getElementById('keypoints');
  const videoCtx = canvas.getContext('2d');
  const keypointCtx = keypointCanvas.getContext('2d');

  canvas.width = videoWidth;
  canvas.height = videoHeight;
  keypointCanvas.width = videoWidth;
  keypointCanvas.height = videoHeight;

  async function poseDetectionFrame() {


    let poses = [];
   
    videoCtx.clearRect(0, 0, videoWidth, videoHeight);
    // Draw video
    videoCtx.save();
    videoCtx.scale(-1, 1);
    videoCtx.translate(-videoWidth, 0);
    // videoCtx.drawImage(video, 0, 0, videoWidth, videoHeight); //this comment disables self-video
    videoCtx.restore();

    // Creates a tensor from an image
    //keeping it in multi-person makes the svg detection better - sachin
    const input = tf.browser.fromPixels(canvas);
    faceDetection = await facemesh.estimateFaces(input, false, false);
    let all_poses = await posenet.estimatePoses(video, {
      flipHorizontal: true,
      decodingMethod: 'multi-person',
      maxDetections: 1,
      scoreThreshold: minPartConfidence,
      nmsRadius: nmsRadius
    });

    poses = poses.concat(all_poses);
    input.dispose();

    keypointCtx.clearRect(0, 0, videoWidth, videoHeight);
    if (guiState.debug.showDetectionDebug) {
      poses.forEach(({score, keypoints}) => {
      if (score >= minPoseConfidence) {
          drawKeypoints(keypoints, minPartConfidence, keypointCtx);
          drawSkeleton(keypoints, minPartConfidence, keypointCtx);
        }
      });
      faceDetection.forEach(face => {
        Object.values(facePartName2Index).forEach(index => {
            let p = face.scaledMesh[index];
            drawPoint(keypointCtx, p[1], p[0], 2, 'red');
        });
      });
    }

    canvasScope.project.clear();

    if (poses.length >= 1 && illustration) {
      Skeleton.flipPose(poses[0]);

      if (faceDetection && faceDetection.length > 0) {
        let face = Skeleton.toFaceFrame(faceDetection[0]);
        illustration.updateSkeleton(poses[0], face);
      } else {
        illustration.updateSkeleton(poses[0], null);
      }
      illustration.draw(canvasScope, videoWidth, videoHeight);

      if (guiState.debug.showIllustrationDebug) {
        illustration.debugDraw(canvasScope);
      }
    }

    canvasScope.project.activeLayer.scale(
      canvasWidth / videoWidth, 
      canvasHeight / videoHeight, 
      new canvasScope.Point(0, 0));



    requestAnimationFrame(poseDetectionFrame);
  }
  poseDetectionFrame();
}
/**
 * Feeds an image to posenet to estimate poses - this is where the magic
 * happens. This function loops with a requestAnimationFrame method.
 */
Feeds an image to posenet to estimate poses - this is where the magic
happens. This function loops with a requestAnimationFrame method.
Feeds an image to posenet to estimate poses - this is where the magic happens . This function loops with a requestAnimationFrame method .
function detectPoseInRealTime(video) {
  const canvas = document.getElementById('output');
  const keypointCanvas = document.getElementById('keypoints');
  const videoCtx = canvas.getContext('2d');
  const keypointCtx = keypointCanvas.getContext('2d');
  canvas.width = videoWidth;
  canvas.height = videoHeight;
  keypointCanvas.width = videoWidth;
  keypointCanvas.height = videoHeight;
  async function poseDetectionFrame() {
    let poses = [];
    videoCtx.clearRect(0, 0, videoWidth, videoHeight);
    videoCtx.save();
    videoCtx.scale(-1, 1);
    videoCtx.translate(-videoWidth, 0);
    videoCtx.restore();
    const input = tf.browser.fromPixels(canvas);
    faceDetection = await facemesh.estimateFaces(input, false, false);
    let all_poses = await posenet.estimatePoses(video, {
      flipHorizontal: true,
      decodingMethod: 'multi-person',
      maxDetections: 1,
      scoreThreshold: minPartConfidence,
      nmsRadius: nmsRadius
    });
    poses = poses.concat(all_poses);
    input.dispose();
    keypointCtx.clearRect(0, 0, videoWidth, videoHeight);
    if (guiState.debug.showDetectionDebug) {
      poses.forEach(({score, keypoints}) => {
      if (score >= minPoseConfidence) {
          drawKeypoints(keypoints, minPartConfidence, keypointCtx);
          drawSkeleton(keypoints, minPartConfidence, keypointCtx);
        }
      });
      faceDetection.forEach(face => {
        Object.values(facePartName2Index).forEach(index => {
            let p = face.scaledMesh[index];
            drawPoint(keypointCtx, p[1], p[0], 2, 'red');
        });
      });
    }
    canvasScope.project.clear();
    if (poses.length >= 1 && illustration) {
      Skeleton.flipPose(poses[0]);
      if (faceDetection && faceDetection.length > 0) {
        let face = Skeleton.toFaceFrame(faceDetection[0]);
        illustration.updateSkeleton(poses[0], face);
      } else {
        illustration.updateSkeleton(poses[0], null);
      }
      illustration.draw(canvasScope, videoWidth, videoHeight);
      if (guiState.debug.showIllustrationDebug) {
        illustration.debugDraw(canvasScope);
      }
    }
    canvasScope.project.activeLayer.scale(
      canvasWidth / videoWidth, 
      canvasHeight / videoHeight, 
      new canvasScope.Point(0, 0));
    requestAnimationFrame(poseDetectionFrame);
  }
  poseDetectionFrame();
}
function detectPoseInRealTime ( video ) { const canvas = document . getElementById ( 'output' ) ; const keypointCanvas = document . getElementById ( 'keypoints' ) ; const videoCtx = canvas . getContext ( '2d' ) ; const keypointCtx = keypointCanvas . getContext ( '2d' ) ; canvas . width = videoWidth ; canvas . height = videoHeight ; keypointCanvas . width = videoWidth ; keypointCanvas . height = videoHeight ; async function poseDetectionFrame ( ) { let poses = [ ] ; videoCtx . clearRect ( 0 , 0 , videoWidth , videoHeight ) ; videoCtx . save ( ) ; videoCtx . scale ( - 1 , 1 ) ; videoCtx . translate ( - videoWidth , 0 ) ; videoCtx . restore ( ) ; const input = tf . browser . fromPixels ( canvas ) ; faceDetection = await facemesh . estimateFaces ( input , false , false ) ; let all_poses = await posenet . estimatePoses ( video , { flipHorizontal : true , decodingMethod : 'multi-person' , maxDetections : 1 , scoreThreshold : minPartConfidence , nmsRadius : nmsRadius } ) ; poses = poses . concat ( all_poses ) ; input . dispose ( ) ; keypointCtx . clearRect ( 0 , 0 , videoWidth , videoHeight ) ; if ( guiState . debug . showDetectionDebug ) { poses . forEach ( ( { score , keypoints } ) => { if ( score >= minPoseConfidence ) { drawKeypoints ( keypoints , minPartConfidence , keypointCtx ) ; drawSkeleton ( keypoints , minPartConfidence , keypointCtx ) ; } } ) ; faceDetection . forEach ( face => { Object . values ( facePartName2Index ) . forEach ( index => { let p = face . scaledMesh [ index ] ; drawPoint ( keypointCtx , p [ 1 ] , p [ 0 ] , 2 , 'red' ) ; } ) ; } ) ; } canvasScope . project . clear ( ) ; if ( poses . length >= 1 && illustration ) { Skeleton . flipPose ( poses [ 0 ] ) ; if ( faceDetection && faceDetection . length > 0 ) { let face = Skeleton . toFaceFrame ( faceDetection [ 0 ] ) ; illustration . updateSkeleton ( poses [ 0 ] , face ) ; } else { illustration . updateSkeleton ( poses [ 0 ] , null ) ; } illustration . draw ( canvasScope , videoWidth , videoHeight ) ; if ( guiState . debug . showIllustrationDebug ) { illustration . debugDraw ( canvasScope ) ; } } canvasScope . project . activeLayer . scale ( canvasWidth / videoWidth , canvasHeight / videoHeight , new canvasScope . Point ( 0 , 0 ) ) ; requestAnimationFrame ( poseDetectionFrame ) ; } poseDetectionFrame ( ) ; }
Feeds an image to posenet to estimate poses - this is where the magic
 happens.
Feeds an image to posenet to estimate poses - this is where the magic happens .
// Draw video // videoCtx.drawImage(video, 0, 0, videoWidth, videoHeight); //this comment disables self-video // Creates a tensor from an image //keeping it in multi-person makes the svg detection better - sachin