使用face-api.js进行实时人脸检测和情绪识别

人脸识别技术一直备受追捧,但训练步骤是其生产就绪的一大障碍。为了绕过这个障碍,让向介绍face-api.js,这是一个基于TensorFlow.js实现的JavaScript人脸识别库。

face-api.js功能强大且易于使用,它只向展示了配置所需的内容。它实现了几种卷积神经网络(CNN),但隐藏了编写神经网络以解决面部检测、识别和地标检测的所有底层层。可以从这里获取库和模型。

在深入任何代码之前,需要设置一个服务器。如果一直在关注,会看到通过直接在浏览器中工作而保持了简单,而没有设置服务器。这种方法直到现在都有效,但如果尝试将face-api.js模型直接服务到浏览器,那么会遇到错误,因为HTML5要求从Web服务器提供网页和图像。

设置服务器的一个简单方法是设置Chrome的Web服务器。启动服务器并按照如下设置:

现在可以通过访问http://127.0.0.1:8887来访问应用程序。

一旦设置了服务器,创建一个HTML文档并导入face-api库:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script> <script type="application/x-javascript" src="face-api.js"></script> </head> <body> <h1>使用face-api.js进行实时情绪检测</h1> <video autoplay muted id="video" width="224" height="224" style="margin: auto;"></video> <div id="prediction">加载中</div> <script type="text/javascript" defer src="index.js"></script> </body> </html>

还需要包括一个视频标签和处理应用程序逻辑的JavaScript文件。这是文档的最终外观。

让继续到JavaScript文件并定义一些重要的变量:

const video = document.getElementById("video"); const text = document.getElementById("prediction");

现在设置函数来开始视频:

function startVideo() { navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; if (navigator.getUserMedia) { navigator.getUserMedia({ video: true }, function(stream) { var video = document.querySelector('video'); video.srcObject = stream; video.onloadedmetadata = function(e) { video.play(); }; }, function(err) { console.log(err.name); }); } else { document.body.innerText = "getUserMedia not supported"; console.log("getUserMedia not supported"); } }

使用face-api.js进行预测。与其下载所有模型,可以像这样从URI加载它们:

let url = "https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights/"; faceapi.nets.tinyFaceDetector.loadFromUri(url + 'tiny_face_detector_model-weights_manifest.json'), faceapi.nets.faceLandmark68Net.loadFromUri(url + 'face_landmark_68_model-weights_manifest.json'), faceapi.nets.faceRecognitionNet.loadFromUri(url + 'face_recognition_model-weights_manifest.json'), faceapi.nets.faceExpressionNet.loadFromUri(url + 'face_expression_model-weights_manifest.json')

face-api.js将情绪分类为七个类别:快乐、悲伤、愤怒、厌恶、恐惧、中性和惊讶。由于对两个主要类别感兴趣,即中性和不高兴,将top_prediction设置为中性。一个人通常被认为是不高兴的,当他们是悲伤的、愤怒的或厌恶的,所以如果这些情绪中的任何一个的预测分数大于中性的预测分数,那么将显示预测的情绪为不高兴。让以字符串格式获取顶级预测:

function prediction_string(obj) { let top_prediction = "neutral"; let maxVal = 0; var str = top_prediction; if (!obj) return str; obj = obj.expressions; for (var p in obj) { if (obj.hasOwnProperty(p)) { if (obj[p] > maxVal) { maxVal = obj[p]; top_prediction = p; if (p === obj.sad || obj.disgusted || obj.angry){ top_prediction = "grumpy"; } } } } return top_prediction; }

最后,需要从face-api模型中获取预测:

const predictions = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()) .withFaceLandmarks() .withFaceExpressions();

代码整合在一起看起来像这样:

const video = document.getElementById("video"); const canvas = document.getElementById("canvas"); const text = document.getElementById("prediction"); Promise.all([ faceapi.nets.tinyFaceDetector.loadFromUri('/models'), faceapi.nets.faceLandmark68Net.loadFromUri('/models'), faceapi.nets.faceRecognitionNet.loadFromUri('/models'), faceapi.nets.faceExpressionNet.loadFromUri('/models'), ]).then(startVideo); function prediction_string(obj) { let top_prediction = "neutral"; let maxVal = 0; var str = top_prediction; if (!obj) return str; obj = obj.expressions; for (var p in obj) { if (obj.hasOwnProperty(p)) { if (obj[p] > maxVal) { maxVal = obj[p]; top_prediction = p; if (p === obj.sad || obj.disgusted || obj.angry){ top_prediction = "grumpy"; } } } } return top_prediction; } function startVideo() { navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; if (navigator.getUserMedia) { navigator.getUserMedia({ video: true }, function(stream) { var video = document.querySelector('video'); video.srcObject = stream; video.onloadedmetadata = function(e) { video.play(); }; }, function(err) { console.log(err.name); }); } else { document.body.innerText = "getUserMedia not supported"; console.log("getUserMedia not supported"); } } video.addEventListener("play", () => { let visitedMsg = true; setInterval(async () => { const predictions = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()) .withFaceLandmarks() .withFaceExpressions(); if (visitedMsg) { text.innerText = "Your expression"; visitedMsg = false; } text.innerHTML = prediction_string(predictions[0]); }, 100); });
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485