使用 face-api 和 Tensorflow.js 进行预训练的 AI 情绪检测





5.00/5 (3投票s)
在本文中,我们将使用另一个预训练模型 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
设置服务器后,创建一个 HTML 文档并导入 face-api 库
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script type="application/x-javascript" src="face-api.js"></script>
我们还需要包含一个视频标签和 JavaScript 文件来处理我们的应用程序逻辑。这是文档的最终外观
<!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>Real-Time grumpiness Detection using face-api.js</h1>
<video autoplay muted id="video" width="224" height="224" style=" margin: auto;"></video>
<div id="prediction">Loading</div>
<script type="text/javascript" defer src="index.js"></script>
</body>
</html>
获取实时视频流
让我们移动到我们的 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);
});
测试
现在在 Chrome Web 服务器(或您选择的任何其他 Web 服务器)中运行您的应用程序。对于 Chrome Web 服务器,请访问 http://127.0.0.1:8887 以查看您的应用程序的实际效果。
下一步是什么?
现在我们已经了解了使用 face-api.js 预测人类面部表情的简便性,我们还能用它做更多的事情吗?在下一篇文章中,我们将预测浏览器中的性别和年龄。