在 Nodejs 中使用 Face API
项目设置
添加 FaceAPI
更新上传端点
绘制检测
正在更新 faceapiService.js
更新上传端点
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
我们将使用vladmandic-face-api,因为它与 tfjs 2.0 兼容。
项目设置
我们将搭建项目环境并安装一些项目所需的软件包。初始设置包括设置用于上传图片和浏览文件/文件夹的 API。npm install express express-fileupload fs path
这是人脸 API,tfjs 也是人脸 API 和 canvas 绘制检测到的点所必需的。npm install @vladmandic/face-api @tensorflow/tfjs canvas
设置 Express API 和文件上传端点。
const express = require("express");
const fileUpload = require("express-fileupload");
const app = express();
const port = process.env.PORT || 3000;
app.use(fileUpload());
app.post("/upload", async (req, res) => {
const { file } = req.files;
console.log(file);
res.send("Successfile upload");
});
app.listen(port, () => {
console.log("Server started on port" + port);
});
在上面的代码中,我将键设置为文件。const { file } = req.files;
我们将使用 Postman 来测试 API,表单数据主体和文件作为键。
添加 FaceAPI
点击此处下载AI模型。你可以随意尝试任何模型,但在这个例子中,我们将只使用SSD MobileNet进行人脸检测。
faceapiService.js
这个文件使用了人脸识别 API。在`main()`函数中,我们初始化人脸识别 API 和 TensorFlow,并定位模型。在`image()`函数中,我们传入上传的图像数据,并将其解码为 TensorFlow 对象。然后,我们将该对象传递给`detect()`函数,它会返回我们上传图像的检测结果。
const path = require("path");
const tf = require("@tensorflow/tfjs-node");
const faceapi = require("@vladmandic/face-api/dist/face-api.node.js");
const modelPathRoot = "./models";
let optionsSSDMobileNet;
async function image(file) {
const decoded = tf.node.decodeImage(file);
const casted = decoded.toFloat();
const result = casted.expandDims(0);
decoded.dispose();
casted.dispose();
return result;
}
async function detect(tensor) {
const result = await faceapi.detectAllFaces(tensor, optionsSSDMobileNet);
return result;
}
async function main(file) {
console.log("FaceAPI single-process test");
await faceapi.tf.setBackend("tensorflow");
await faceapi.tf.enableProdMode();
await faceapi.tf.ENV.set("DEBUG", false);
await faceapi.tf.ready();
console.log(
`Version: TensorFlow/JS ${faceapi.tf?.version_core} FaceAPI ${
faceapi.version.faceapi
} Backend: ${faceapi.tf?.getBackend()}`
);
console.log("Loading FaceAPI models");
const modelPath = path.join(__dirname, modelPathRoot);
await faceapi.nets.ssdMobilenetv1.loadFromDisk(modelPath);
optionsSSDMobileNet = new faceapi.SsdMobilenetv1Options({
minConfidence: 0.5,
});
const tensor = await image(file);
const result = await detect(tensor);
console.log("Detected faces:", result.length);
tensor.dispose();
return result;
}
module.exports = {
detect: main,
};
更新上传端点
我们将更新端点并测试其是否正常工作。
app.post("/upload", async (req, res) => {
const { file } = req.files;
const result = await faceApiService.detect(file.data);
res.json({
detectedFaces: result.length,
});
});
绘制检测
现在我们将把检测到的结果添加到图像中,看看它是否真的能检测到正确的人脸。
saveFile.js
我们将创建一个新的 utils 文件夹,并将此文件添加到其中,以便添加一个用于保存检测到的图像的实用程序。我们还会添加一个 out 文件夹,用于存放检测到的图像。
const fs = require("fs");
const path = require("path");
const baseDir = path.resolve(__dirname, "../out");
function saveFile(fileName, buf) {
if (!fs.existsSync(baseDir)) {
fs.mkdirSync(baseDir);
}
fs.writeFileSync(path.resolve(baseDir, fileName), buf);
}
module.exports = {
saveFile,
};
正在更新 faceapiService.js
我们正在添加这段代码来绘制检测结果。
const canvas = require("canvas");
const { Canvas, Image, ImageData } = canvas;
faceapi.env.monkeyPatch({ Canvas, Image, ImageData });
async function main(file, filename){
//...Existing code
const result = await detect(tensor);
console.log("Detected faces:", result.length);
const canvasImg = await canvas.loadImage(file);
const out = await faceapi.createCanvasFromMedia(canvasImg);
faceapi.draw.drawDetections(out, result);
save.saveFile(filename, out.toBuffer("image/jpeg"));
console.log(`done, saved results to ${filename}`);
}
更新上传端点
现在我们快要完成了,我们将展示已保存的图像,并在上传响应中添加一个 URL。
app.post("/upload", async (req, res) => {
const { file } = req.files;
const result = await faceApiService.detect(file.data, file.name);
res.json({
detectedFaces: result.length,
url: `http://localhost:3000/out/${file.name}`,
});
});
app.use("/out", express.static("out"));
现在我们再试一次邮递员。 好了,我们已经检测到了人脸,可以绘制并显示图像了。

我还创建了一个 GitHub 仓库以供参考。face -api。
文章来源:https://dev.to/kvntzn/using-face-api-in-nodejs-38aj

