ai-face-detection
Version:
This is simple face detection using face-api.js and tensorflow.js
103 lines • 11.8 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.faceDetect = void 0;
const fs_1 = __importDefault(require("fs"));
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const canvas_1 = __importStar(require("canvas"));
const faceapi = __importStar(require("@vladmandic/face-api"));
const crypto_1 = require("crypto");
const logger_1 = __importDefault(require("./helpers/logger"));
const processDetection_1 = require("./processDetection");
const axios_1 = __importDefault(require("axios"));
const modelPathRoot = path_1.default.resolve(__dirname + '../../../weights');
const minConfidence = 0.15;
const maxResults = 5;
async function faceDetect(imagePath) {
const inFile = await processInput(imagePath);
faceapi.env.monkeyPatch({
Canvas: canvas_1.default.Canvas,
Image: canvas_1.default.Image,
ImageData: canvas_1.default.ImageData,
});
// @ts-expect-error
await faceapi.tf.setBackend('tensorflow');
// @ts-expect-error
await faceapi.tf.enableProdMode();
// @ts-expect-error
await faceapi.tf.ready();
faceapi.tf.ENV.set('DEBUG', false);
logger_1.default.info(
// @ts-expect-error
`Version: TensorFlow/JS ${faceapi.tf?.version_core} FaceAPI ${faceapi.version
// @ts-expect-error
} Backend: ${faceapi.tf?.getBackend()}`);
logger_1.default.info('Loading FaceAPI models');
const modelPath = modelPathRoot;
await faceapi.nets.ssdMobilenetv1.loadFromDisk(modelPath);
await faceapi.nets.ageGenderNet.loadFromDisk(modelPath);
await faceapi.nets.faceLandmark68Net.loadFromDisk(modelPath);
await faceapi.nets.faceRecognitionNet.loadFromDisk(modelPath);
await faceapi.nets.faceExpressionNet.loadFromDisk(modelPath);
const optionsSSDMobileNet = new faceapi.SsdMobilenetv1Options({
minConfidence,
maxResults,
});
const junkDir = path_1.default.resolve(path_1.default.join(__dirname, '../junk'));
if (!fs_1.default.existsSync(junkDir)) {
await promises_1.default.mkdir(junkDir);
}
const exitImage = path_1.default.resolve(path_1.default.join(junkDir, `./${(0, crypto_1.randomUUID)()}.jpg`));
const outFile = fs_1.default.createWriteStream(exitImage);
const canvasImage = await (0, canvas_1.loadImage)(inFile, outFile);
const result = await (0, processDetection_1.processDetection)(canvasImage, optionsSSDMobileNet);
outFile.on('finish', () => {
promises_1.default.unlink(path_1.default.resolve(exitImage));
});
outFile.close();
return result;
}
exports.faceDetect = faceDetect;
const processInput = async (input) => {
if (typeof input !== 'string' && !(input instanceof Buffer)) {
throw new Error('Input type should be instance of Buffer or string');
}
if (input instanceof Buffer) {
return input;
}
// check if string is url
if (input.startsWith('http')) {
// read from url
const response = await axios_1.default.get(input, { responseType: 'arraybuffer' });
return Buffer.from(response.data, 'binary');
}
const inFile = await promises_1.default.readFile(input);
return inFile;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjZURldGVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvZmFjZURldGVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDRDQUFtQjtBQUNuQiwyREFBb0M7QUFDcEMsZ0RBQXVCO0FBQ3ZCLGlEQUEwQztBQUMxQyw4REFBK0M7QUFDL0MsbUNBQW1DO0FBQ25DLDhEQUFxQztBQUNyQyx5REFBcUQ7QUFDckQsa0RBQXlCO0FBRXpCLE1BQU0sYUFBYSxHQUFHLGNBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxHQUFHLGtCQUFrQixDQUFDLENBQUE7QUFDbEUsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFBO0FBQzFCLE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQTtBQUViLEtBQUssVUFBVSxVQUFVLENBQUMsU0FBMEI7SUFDekQsTUFBTSxNQUFNLEdBQUcsTUFBTSxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUE7SUFFNUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUM7UUFDdEIsTUFBTSxFQUFFLGdCQUFNLENBQUMsTUFBTTtRQUNyQixLQUFLLEVBQUUsZ0JBQU0sQ0FBQyxLQUFLO1FBQ25CLFNBQVMsRUFBRSxnQkFBTSxDQUFDLFNBQVM7S0FDNUIsQ0FBQyxDQUFBO0lBRUYsbUJBQW1CO0lBQ25CLE1BQU0sT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUE7SUFDekMsbUJBQW1CO0lBQ25CLE1BQU0sT0FBTyxDQUFDLEVBQUUsQ0FBQyxjQUFjLEVBQUUsQ0FBQTtJQUNqQyxtQkFBbUI7SUFDbkIsTUFBTSxPQUFPLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFBO0lBQ3hCLE9BQU8sQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUE7SUFFbEMsZ0JBQU0sQ0FBQyxJQUFJ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O0lBQ0QsTUFBTSxNQUFNLEdBQUcsTUFBTSxrQkFBVSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUMvQyxPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tICdmcydcbmltcG9ydCBmc1Byb21pc2VzIGZyb20gJ2ZzL3Byb21pc2VzJ1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcbmltcG9ydCBjYW52YXMsIHsgbG9hZEltYWdlIH0gZnJvbSAnY2FudmFzJ1xuaW1wb3J0ICogYXMgZmFjZWFwaSBmcm9tICdAdmxhZG1hbmRpYy9mYWNlLWFwaSdcbmltcG9ydCB7IHJhbmRvbVVVSUQgfSBmcm9tICdjcnlwdG8nXG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4vaGVscGVycy9sb2dnZXInXG5pbXBvcnQgeyBwcm9jZXNzRGV0ZWN0aW9uIH0gZnJvbSAnLi9wcm9jZXNzRGV0ZWN0aW9uJ1xuaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJ1xuXG5jb25zdCBtb2RlbFBhdGhSb290ID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSArICcuLi8uLi8uLi93ZWlnaHRzJylcbmNvbnN0IG1pbkNvbmZpZGVuY2UgPSAwLjE1XG5jb25zdCBtYXhSZXN1bHRzID0gNVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmFjZURldGVjdChpbWFnZVBhdGg6IHN0cmluZyB8IEJ1ZmZlcikge1xuICBjb25zdCBpbkZpbGUgPSBhd2FpdCBwcm9jZXNzSW5wdXQoaW1hZ2VQYXRoKVxuXG4gIGZhY2VhcGkuZW52Lm1vbmtleVBhdGNoKHtcbiAgICBDYW52YXM6IGNhbnZhcy5DYW52YXMsXG4gICAgSW1hZ2U6IGNhbnZhcy5JbWFnZSxcbiAgICBJbWFnZURhdGE6IGNhbnZhcy5JbWFnZURhdGEsXG4gIH0pXG5cbiAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICBhd2FpdCBmYWNlYXBpLnRmLnNldEJhY2tlbmQoJ3RlbnNvcmZsb3cnKVxuICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gIGF3YWl0IGZhY2VhcGkudGYuZW5hYmxlUHJvZE1vZGUoKVxuICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gIGF3YWl0IGZhY2VhcGkudGYucmVhZHkoKVxuICBmYWNlYXBpLnRmLkVOVi5zZXQoJ0RFQlVHJywgZmFsc2UpXG5cbiAgbG9nZ2VyLmluZm8oXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgIGBWZXJzaW9uOiBUZW5zb3JGbG93L0pTICR7ZmFjZWFwaS50Zj8udmVyc2lvbl9jb3JlfSBGYWNlQVBJICR7XG4gICAgICBmYWNlYXBpLnZlcnNpb25cbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICB9IEJhY2tlbmQ6ICR7ZmFjZWFwaS50Zj8uZ2V0QmFja2VuZCgpfWBcbiAgKVxuXG4gIGxvZ2dlci5pbmZvKCdMb2FkaW5nIEZhY2VBUEkgbW9kZWxzJylcbiAgY29uc3QgbW9kZWxQYXRoID0gbW9kZWxQYXRoUm9vdFxuICBhd2FpdCBmYWNlYXBpLm5ldHMuc3NkTW9iaWxlbmV0djEubG9hZEZyb21EaXNrKG1vZGVsUGF0aClcbiAgYXdhaXQgZmFjZWFwaS5uZXRzLmFnZUdlbmRlck5ldC5sb2FkRnJvbURpc2sobW9kZWxQYXRoKVxuICBhd2FpdCBmYWNlYXBpLm5ldHMuZmFjZUxhbmRtYXJrNjhOZXQubG9hZEZyb21EaXNrKG1vZGVsUGF0aClcbiAgYXdhaXQgZmFjZWFwaS5uZXRzLmZhY2VSZWNvZ25pdGlvbk5ldC5sb2FkRnJvbURpc2sobW9kZWxQYXRoKVxuICBhd2FpdCBmYWNlYXBpLm5ldHMuZmFjZUV4cHJlc3Npb25OZXQubG9hZEZyb21EaXNrKG1vZGVsUGF0aClcbiAgY29uc3Qgb3B0aW9uc1NTRE1vYmlsZU5ldCA9IG5ldyBmYWNlYXBpLlNzZE1vYmlsZW5ldHYxT3B0aW9ucyh7XG4gICAgbWluQ29uZmlkZW5jZSxcbiAgICBtYXhSZXN1bHRzLFxuICB9KVxuXG4gIGNvbnN0IGp1bmtEaXIgPSBwYXRoLnJlc29sdmUocGF0aC5qb2luKF9fZGlybmFtZSwgJy4uL2p1bmsnKSlcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGp1bmtEaXIpKSB7XG4gICAgYXdhaXQgZnNQcm9taXNlcy5ta2RpcihqdW5rRGlyKVxuICB9XG4gIGNvbnN0IGV4aXRJbWFnZSA9IHBhdGgucmVzb2x2ZShwYXRoLmpvaW4oanVua0RpciwgYC4vJHtyYW5kb21VVUlEKCl9LmpwZ2ApKVxuICBjb25zdCBvdXRGaWxlID0gZnMuY3JlYXRlV3JpdGVTdHJlYW0oZXhpdEltYWdlKVxuXG4gIGNvbnN0IGNhbnZhc0ltYWdlID0gYXdhaXQgbG9hZEltYWdlKGluRmlsZSwgb3V0RmlsZSlcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHJvY2Vzc0RldGVjdGlvbihjYW52YXNJbWFnZSwgb3B0aW9uc1NTRE1vYmlsZU5ldClcblxuICBvdXRGaWxlLm9uKCdmaW5pc2gnLCAoKSA9PiB7XG4gICAgZnNQcm9taXNlcy51bmxpbmsocGF0aC5yZXNvbHZlKGV4aXRJbWFnZSkpXG4gIH0pXG4gIG91dEZpbGUuY2xvc2UoKVxuXG4gIHJldHVybiByZXN1bHRcbn1cblxuY29uc3QgcHJvY2Vzc0lucHV0ID0gYXN5bmMgKGlucHV0OiBzdHJpbmcgfCBCdWZmZXIpOiBQcm9taXNlPEJ1ZmZlcj4gPT4ge1xuICBpZiAodHlwZW9mIGlucHV0ICE9PSAnc3RyaW5nJyAmJiAhKGlucHV0IGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgdHlwZSBzaG91bGQgYmUgaW5zdGFuY2Ugb2YgQnVmZmVyIG9yIHN0cmluZycpXG4gIH1cbiAgaWYgKGlucHV0IGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgcmV0dXJuIGlucHV0XG4gIH1cbiAgLy8gY2hlY2sgaWYgc3RyaW5nIGlzIHVybFxuICBpZiAoaW5wdXQuc3RhcnRzV2l0aCgnaHR0cCcpKSB7XG4gICAgLy8gcmVhZCBmcm9tIHVybFxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXhpb3MuZ2V0KGlucHV0LCB7IHJlc3BvbnNlVHlwZTogJ2FycmF5YnVmZmVyJyB9KVxuICAgIHJldHVybiBCdWZmZXIuZnJvbShyZXNwb25zZS5kYXRhLCAnYmluYXJ5JylcbiAgfVxuICBjb25zdCBpbkZpbGUgPSBhd2FpdCBmc1Byb21pc2VzLnJlYWRGaWxlKGlucHV0KVxuICByZXR1cm4gaW5GaWxlXG59XG4iXX0=
;