import path from 'path' // import nodejs bindings to native tensorflow, // not required, but will speed up things drastically (python required) import '@tensorflow/tfjs-node' import * as canvas from 'canvas' import * as faceapi from 'face-api.js' // patch nodejs environment, we need to provide an implementation of // HTMLCanvasElement and HTMLImageElement const { Canvas, Image, ImageData } = canvas faceapi.env.monkeyPatch({ Canvas, Image, ImageData } as any) export default { faceDetectionNet: faceapi.nets.ssdMobilenetv1, faceLandmarkNet: faceapi.nets.faceLandmark68Net, loadedNet: false, async init() { if (this.loadedNet) return await this.faceDetectionNet.loadFromDisk( path.join(__dirname, '..', '..', 'weights') ) await this.faceLandmarkNet.loadFromDisk( path.join(__dirname, '..', '..', 'weights') ) this.loadedNet = true }, async drawFaceOutlines(imgBuffer: Buffer) { await this.init() const img: any = await canvas.loadImage(imgBuffer) const detections = await faceapi .detectAllFaces(img, this.getFaceDetectorOptions(this.faceDetectionNet)) .withFaceLandmarks() const out: any = faceapi.createCanvasFromMedia(img) faceapi.draw.drawDetections(out, detections) return [detections, out.toBuffer('image/jpeg')] }, getFaceDetectorOptions(net: any) { // SsdMobilenetv1Options const minConfidence = 0.5 // TinyFaceDetectorOptions const inputSize = 408 const scoreThreshold = 0.5 return net === faceapi.nets.ssdMobilenetv1 ? new faceapi.SsdMobilenetv1Options({ minConfidence }) : new faceapi.TinyFaceDetectorOptions({ inputSize, scoreThreshold }) }, }