document and remove optional dependencies
parent
870eebedfa
commit
7a6f7d96b7
|
@ -9,7 +9,7 @@
|
|||
|
||||
## Changelog
|
||||
|
||||
### **HEAD -> master** 2022/08/16 mandic00@live.com
|
||||
### **HEAD -> master** 2022/08/22 mandic00@live.com
|
||||
|
||||
|
||||
### **release: 1.7.1** 2022/07/25 mandic00@live.com
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
import * as faceapi from '../dist/face-api.esm.js';
|
||||
/**
|
||||
* FaceAPI Demo for Browsers
|
||||
* Loaded via `index.html`
|
||||
*/
|
||||
|
||||
import * as faceapi from '../dist/face-api.esm.js'; // use when in dev mode
|
||||
// import * as faceapi from '@vladmandic/face-api'; // use when downloading face-api as npm
|
||||
|
||||
// configuration options
|
||||
const modelPath = '../model/'; // path to model folder that will be loaded using http
|
||||
// const modelPath = 'https://vladmandic.github.io/face-api/model/'; // path to model folder that will be loaded using http
|
||||
// const modelPath = 'https://cdn.jsdelivr.net/npm/@vladmandic/face-api/model/'; // path to model folder that will be loaded using http
|
||||
const imgSize = 800; // maximum image size in pixels
|
||||
const minScore = 0.3; // minimum score
|
||||
const maxResults = 10; // maximum number of results to return
|
||||
|
@ -13,8 +19,7 @@ const str = (json) => (json ? JSON.stringify(json).replace(/{|}|"|\[|\]/g, '').r
|
|||
|
||||
// helper function to print strings to html document as a log
|
||||
function log(...txt) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(...txt);
|
||||
console.log(...txt); // eslint-disable-line no-console
|
||||
const div = document.getElementById('log');
|
||||
if (div) div.innerHTML += `<br>${txt}`;
|
||||
}
|
||||
|
@ -67,8 +72,7 @@ function faces(name, title, id, data) {
|
|||
|
||||
// helper function to draw processed image and its results
|
||||
function print(title, img, data) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Results:', title, img, data);
|
||||
console.log('Results:', title, img, data); // eslint-disable-line no-console
|
||||
const el = new Image();
|
||||
el.id = Math.floor(Math.random() * 100000).toString();
|
||||
el.src = img;
|
||||
|
@ -174,8 +178,7 @@ async function main() {
|
|||
print('SSDMobileNet:', img, dataSSDMobileNet);
|
||||
} catch (err) {
|
||||
log(`Image: ${img} Error during processing ${str(err)}`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
console.error(err); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
/**
|
||||
* FaceAPI Demo for NodeJS
|
||||
* - Uses external library [canvas](https://www.npmjs.com/package/canvas) to decode image
|
||||
* - Loads image from provided param
|
||||
* - Outputs results to console
|
||||
*/
|
||||
|
||||
// canvas library provides full canvas (load/draw/write) functionality for nodejs
|
||||
// must be installed manually as it just a demo dependency and not actual face-api dependency
|
||||
const canvas = require('canvas'); // eslint-disable-line node/no-missing-require
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const process = require('process');
|
||||
const log = require('@vladmandic/pilogger');
|
||||
const canvas = require('canvas');
|
||||
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
|
||||
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before face-api
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
const faceapi = require('../dist/face-api.node.js'); // use this when using face-api in dev mode
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
|
||||
const modelPathRoot = '../model';
|
||||
const imgPathRoot = './demo'; // modify to include your sample images
|
||||
|
@ -50,11 +57,9 @@ async function main() {
|
|||
faceapi.env.monkeyPatch({ Canvas: canvas.Canvas, Image: canvas.Image, ImageData: canvas.ImageData });
|
||||
|
||||
await faceapi.tf.setBackend('tensorflow');
|
||||
await faceapi.tf.enableProdMode();
|
||||
await faceapi.tf.ENV.set('DEBUG', false);
|
||||
await faceapi.tf.ready();
|
||||
|
||||
log.state(`Version: TensorFlow/JS ${faceapi.tf?.version_core} FaceAPI ${faceapi.version} Backend: ${faceapi.tf?.getBackend()}`);
|
||||
log.state(`Version: FaceAPI ${faceapi.version} TensorFlow/JS ${tf.version_core} Backend: ${faceapi.tf?.getBackend()}`);
|
||||
|
||||
log.info('Loading FaceAPI models');
|
||||
const modelPath = path.join(__dirname, modelPathRoot);
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
const fs = require('fs');
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, node/no-unpublished-require
|
||||
const image = require('@canvas/image'); // @canvas/image can decode jpeg, png, webp
|
||||
const log = require('@vladmandic/pilogger');
|
||||
/**
|
||||
* FaceAPI Demo for NodeJS
|
||||
* - Uses external library [@canvas/image](https://www.npmjs.com/package/@canvas/image) to decode image
|
||||
* - Loads image from provided param
|
||||
* - Outputs results to console
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
|
||||
// @canvas/image can decode jpeg, png, webp
|
||||
// must be installed manually as it just a demo dependency and not actual face-api dependency
|
||||
const image = require('@canvas/image'); // eslint-disable-line node/no-missing-require
|
||||
const fs = require('fs');
|
||||
const log = require('@vladmandic/pilogger');
|
||||
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before face-api
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
const faceapi = require('../dist/face-api.node.js'); // use this when using face-api in dev mode
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
|
||||
const modelPath = 'model/';
|
||||
const imageFile = 'demo/sample1.jpg';
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
/**
|
||||
* FaceAPI Demo for NodeJS
|
||||
* - Analyzes face descriptors from source (image file or folder containing multiple image files)
|
||||
* - Analyzes face descriptor from target
|
||||
* - Finds best match
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const log = require('@vladmandic/pilogger');
|
||||
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
|
||||
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before face-api
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
const faceapi = require('../dist/face-api.node.js'); // use this when using face-api in dev mode
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
|
||||
let optionsSSDMobileNet;
|
||||
const minConfidence = 0.1;
|
||||
|
@ -33,6 +38,8 @@ async function getDescriptors(imageFile) {
|
|||
}
|
||||
|
||||
async function registerImage(inputFile) {
|
||||
if (!inputFile.toLowerCase().endsWith('jpg') && !inputFile.toLowerCase().endsWith('png') && !inputFile.toLowerCase().endsWith('gif')) return;
|
||||
log.data('Registered:', inputFile);
|
||||
const descriptors = await getDescriptors(inputFile);
|
||||
for (const descriptor of descriptors) {
|
||||
const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(inputFile, [descriptor]);
|
||||
|
@ -60,14 +67,18 @@ async function main() {
|
|||
await initFaceAPI();
|
||||
log.info('Input:', process.argv[2]);
|
||||
if (fs.statSync(process.argv[2]).isFile()) {
|
||||
await registerImage(process.argv[2]);
|
||||
await registerImage(process.argv[2]); // register image
|
||||
} else if (fs.statSync(process.argv[2]).isDirectory()) {
|
||||
const dir = fs.readdirSync(process.argv[2]);
|
||||
for (const f of dir) await registerImage(path.join(process.argv[2], f));
|
||||
for (const f of dir) await registerImage(path.join(process.argv[2], f)); // register all images in a folder
|
||||
}
|
||||
log.info('Comparing:', process.argv[3], 'Descriptors:', labeledFaceDescriptors.length);
|
||||
if (labeledFaceDescriptors.length > 0) {
|
||||
const bestMatch = await findBestMatch(process.argv[3]); // find best match to all registered images
|
||||
log.data('Match:', bestMatch);
|
||||
} else {
|
||||
log.warn('No registered faces');
|
||||
}
|
||||
log.info('Descriptors:', labeledFaceDescriptors.length);
|
||||
const bestMatch = await findBestMatch(process.argv[3]);
|
||||
log.data('Match:', bestMatch);
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
// @ts-nocheck
|
||||
/**
|
||||
* FaceAPI Demo for NodeJS
|
||||
* - Used by `node-multiprocess.js`
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const log = require('@vladmandic/pilogger');
|
||||
|
||||
// workers actual import tfjs and faceapi modules
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
|
||||
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before face-api
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
const faceapi = require('../dist/face-api.node.js'); // use this when using face-api in dev mode
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
|
||||
// options used by faceapi
|
||||
const modelPathRoot = '../model';
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
* FaceAPI Demo for NodeJS
|
||||
* - Starts multiple worker processes and uses them as worker pool to process all input images
|
||||
* - Images are enumerated in main process and sent for processing to worker processes via ipc
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const log = require('@vladmandic/pilogger'); // this is my simple logger with few extra features
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
/**
|
||||
* FaceAPI Demo for NodeJS
|
||||
* - Loads image
|
||||
* - Outputs results to console
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
const faceapi = require('../dist/face-api.node.js'); // use this when using face-api in dev mode
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
|
||||
async function main() {
|
||||
await faceapi.nets.ssdMobilenetv1.loadFromDisk('model'); // load models from a specific patch
|
||||
|
@ -19,8 +25,7 @@ async function main() {
|
|||
.withFaceDescriptors()
|
||||
.withAgeAndGender();
|
||||
faceapi.tf.dispose([decodeT, expandT]); // dispose tensors to avoid memory leaks
|
||||
// eslint-disable-next-line no-console
|
||||
console.log({ result }); // print results
|
||||
console.log({ result }); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
14
demo/node.js
14
demo/node.js
|
@ -1,12 +1,18 @@
|
|||
/**
|
||||
* FaceAPI Demo for NodeJS
|
||||
* - Uses external library [node-fetch](https://www.npmjs.com/package/node-fetch) to load images via http
|
||||
* - Loads image from provided param
|
||||
* - Outputs results to console
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const process = require('process');
|
||||
const path = require('path');
|
||||
const log = require('@vladmandic/pilogger');
|
||||
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars, @typescript-eslint/no-unused-vars
|
||||
const tf = require('@tensorflow/tfjs-node'); // in nodejs environments tfjs-node is required to be loaded before face-api
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
const faceapi = require('../dist/face-api.node.js'); // use this when using face-api in dev mode
|
||||
// const faceapi = require('@vladmandic/face-api'); // use this when face-api is installed as module (majority of use cases)
|
||||
|
||||
const modelPathRoot = '../model';
|
||||
const imgPathRoot = './demo'; // modify to include your sample images
|
||||
|
@ -87,11 +93,9 @@ async function main() {
|
|||
log.header();
|
||||
log.info('FaceAPI single-process test');
|
||||
|
||||
fetch = (await import('node-fetch')).default;
|
||||
fetch = (await import('node-fetch')).default; // eslint-disable-line node/no-missing-import
|
||||
|
||||
await faceapi.tf.setBackend('tensorflow');
|
||||
await faceapi.tf.enableProdMode();
|
||||
await faceapi.tf.ENV.set('DEBUG', false);
|
||||
await faceapi.tf.ready();
|
||||
|
||||
log.state(`Version: TensorFlow/JS ${faceapi.tf?.version_core} FaceAPI ${faceapi.version} Backend: ${faceapi.tf?.getBackend()}`);
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
import * as faceapi from '../dist/face-api.esm.js';
|
||||
/**
|
||||
* FaceAPI Demo for Browsers
|
||||
* Loaded via `webcam.html`
|
||||
*/
|
||||
|
||||
import * as faceapi from '../dist/face-api.esm.js'; // use when in dev mode
|
||||
// import * as faceapi from '@vladmandic/face-api'; // use when downloading face-api as npm
|
||||
|
||||
// configuration options
|
||||
const modelPath = '../model/'; // path to model folder that will be loaded using http
|
||||
// const modelPath = 'https://vladmandic.github.io/face-api/model/'; // path to model folder that will be loaded using http
|
||||
// const modelPath = 'https://cdn.jsdelivr.net/npm/@vladmandic/face-api/model/'; // path to model folder that will be loaded using http
|
||||
const minScore = 0.2; // minimum score
|
||||
const maxResults = 5; // maximum number of results to return
|
||||
let optionsSSDMobileNet;
|
||||
|
@ -17,8 +23,7 @@ function str(json) {
|
|||
|
||||
// helper function to print strings to html document as a log
|
||||
function log(...txt) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(...txt);
|
||||
console.log(...txt); // eslint-disable-line no-console
|
||||
const div = document.getElementById('log');
|
||||
if (div) div.innerHTML += `<br>${txt}`;
|
||||
}
|
||||
|
|
11
package.json
11
package.json
|
@ -41,11 +41,6 @@
|
|||
"tensorflowjs",
|
||||
"tfjs"
|
||||
],
|
||||
"optionalDependencies": {
|
||||
"@canvas/image": "^1.0.1",
|
||||
"canvas": "^2.9.3",
|
||||
"node-fetch": "^3.2.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/api-extractor": "^7.29.3",
|
||||
"@tensorflow/tfjs": "^3.19.0",
|
||||
|
@ -59,10 +54,10 @@
|
|||
"@tensorflow/tfjs-layers": "^3.19.0",
|
||||
"@tensorflow/tfjs-node": "^3.19.0",
|
||||
"@tensorflow/tfjs-node-gpu": "^3.19.0",
|
||||
"@types/node": "^18.7.9",
|
||||
"@types/node": "^18.7.11",
|
||||
"@types/offscreencanvas": "^2019.7.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.1",
|
||||
"@typescript-eslint/parser": "^5.33.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.34.0",
|
||||
"@typescript-eslint/parser": "^5.34.0",
|
||||
"@vladmandic/build": "^0.7.10",
|
||||
"@vladmandic/pilogger": "^0.4.6",
|
||||
"@vladmandic/tfjs": "github:vladmandic/tfjs",
|
||||
|
|
|
@ -1,4 +1 @@
|
|||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
|
||||
export * from '@tensorflow/tfjs';
|
||||
|
|
|
@ -1,4 +1 @@
|
|||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
|
||||
export * from '@tensorflow/tfjs-node-gpu';
|
||||
|
|
|
@ -1,5 +1,2 @@
|
|||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
|
||||
export * from '@tensorflow/tfjs';
|
||||
export * from '@tensorflow/tfjs-backend-wasm';
|
||||
|
|
|
@ -1,4 +1 @@
|
|||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
|
||||
export * from '@tensorflow/tfjs-node';
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, node/no-unpublished-require
|
||||
const log = require('@vladmandic/pilogger');
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, node/no-unpublished-require
|
||||
const tf = require('@tensorflow/tfjs-node');
|
||||
const faceapi = require('../dist/face-api.node.js'); // this is equivalent to '@vladmandic/faceapi'
|
||||
|
||||
|
|
Loading…
Reference in New Issue