JSFiddle - React, Tailwind, and code Playground

Example of Multi face analysis with SDK for hapu.ai

by morphcast

HTML

<script src="https://ai-sdk.morphcast.com/v1.15/ai-sdk.js"></script>
Il seguente snippet:<br />
- Preleva un frame da camera<br />
- Analizza la prima faccia e predice l'emozione dominante<br />
- Se vi sono altre facce nello stesso frame, i ritagli delle facce vengono passati singolarmente come input al SDK<br />
- Per ogni faccia viene predetta l'emozione dominante, in sequenza. <br />
- Quando è terminata l'analisi delle facce nello stesso frame, viene prelevato un nuovo frame da camera, e così via, per 20 secondi.<br />

JavaScript

/*
 	Creates a pre-built camera source
*/
const cameraSource = CY.createSource.fromCamera({
  constraints: {
    audio: false,
    video: {
      width: 1280,
      height: 720
    }
  }
});


let crtImgData;
let resolver;
let nextFace = null;


/*
 	Wraps the camera source above
*/
const customSource = {
  /*
    frame producer
  */
  analyzeFrame(imageData) {
    if (resolver) {
      resolver(imageData);
      resolver = null;
    } else {
      crtImgData = imageData;
    }
  },
  /*
    frame consumer
  */
  getFrame(...args) {
    if (crtImgData) {
      const p = Promise.resolve(crtImgData);
      crtImgData = null;
      return p;
    } else {
      return new Promise(res => resolver = res);
    }
  },
  start() {
    return cameraSource.start();
  },
  stop() {
    return cameraSource.stop();
  },
  get stopped() {
    return cameraSource.stopped;
  }
};

CY.loader()
  .licenseKey("2b215ceb8279b8a535a7ad8e2467be598166a5bf30c9") //  key for hapu.ai
  .source(customSource)
  .addModule(CY.modules().FACE_DETECTOR.name, {
    multiFace: true
  }) // disables tracker for multi face analysis
  .addModule(CY.modules().FACE_EMOTION.name, {
    smoothness: 0
    // uses raw output for multi face analysis
  })
  .load().then(({
    start,
    stop
  }) => {
    start().then(() => serveNextFrame());
    setTimeout(() => stop(), 20000);
  }).catch((err) => {
    console.error(err);
  });
  

let frameArray = [];
window.addEventListener(CY.modules().EVENT_BARRIER.eventName, (evt) => {
  //console.log("EVENT_BARRIER", evt.detail); 
  const faces = evt.detail.face_detector.faces;
  
  if (evt.detail.face_emotion) {
  	const dominantEmotion = evt.detail.face_emotion.dominantEmotion; 
  	showResult(faces[0], dominantEmotion);
  }
  
  if (faces.length > 1) {
    frameArray = frameArray.concat(faces.slice(1));
  }
  serveNextFrame();
});

function getFrame() {
  if (frameArray.length > 0) {
    console.log('analyzing another face in the same frame');
    count++;
   ...