document and remove optional dependencies

pull/130/head
Vladimir Mandic 2022-08-23 08:21:20 -04:00
parent 870eebedfa
commit 7a6f7d96b7
16 changed files with 95 additions and 67 deletions

View File

@ -9,7 +9,7 @@
## Changelog ## 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 ### **release: 1.7.1** 2022/07/25 mandic00@live.com

View File

@ -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 // configuration options
const modelPath = '../model/'; // path to model folder that will be loaded using http 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 imgSize = 800; // maximum image size in pixels
const minScore = 0.3; // minimum score const minScore = 0.3; // minimum score
const maxResults = 10; // maximum number of results to return 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 // helper function to print strings to html document as a log
function log(...txt) { function log(...txt) {
// eslint-disable-next-line no-console console.log(...txt); // eslint-disable-line no-console
console.log(...txt);
const div = document.getElementById('log'); const div = document.getElementById('log');
if (div) div.innerHTML += `<br>${txt}`; 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 // helper function to draw processed image and its results
function print(title, img, data) { function print(title, img, data) {
// eslint-disable-next-line no-console console.log('Results:', title, img, data); // eslint-disable-line no-console
console.log('Results:', title, img, data);
const el = new Image(); const el = new Image();
el.id = Math.floor(Math.random() * 100000).toString(); el.id = Math.floor(Math.random() * 100000).toString();
el.src = img; el.src = img;
@ -174,8 +178,7 @@ async function main() {
print('SSDMobileNet:', img, dataSSDMobileNet); print('SSDMobileNet:', img, dataSSDMobileNet);
} catch (err) { } catch (err) {
log(`Image: ${img} Error during processing ${str(err)}`); log(`Image: ${img} Error during processing ${str(err)}`);
// eslint-disable-next-line no-console console.error(err); // eslint-disable-line no-console
console.error(err);
} }
} }
} }

View File

@ -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 fs = require('fs');
const path = require('path'); const path = require('path');
const process = require('process'); const process = require('process');
const log = require('@vladmandic/pilogger'); 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 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('../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 modelPathRoot = '../model';
const imgPathRoot = './demo'; // modify to include your sample images 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 }); faceapi.env.monkeyPatch({ Canvas: canvas.Canvas, Image: canvas.Image, ImageData: canvas.ImageData });
await faceapi.tf.setBackend('tensorflow'); await faceapi.tf.setBackend('tensorflow');
await faceapi.tf.enableProdMode();
await faceapi.tf.ENV.set('DEBUG', false);
await faceapi.tf.ready(); 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'); log.info('Loading FaceAPI models');
const modelPath = path.join(__dirname, modelPathRoot); const modelPath = path.join(__dirname, modelPathRoot);

View File

@ -1,12 +1,18 @@
const fs = require('fs'); /**
// eslint-disable-next-line import/no-extraneous-dependencies, node/no-unpublished-require * FaceAPI Demo for NodeJS
const image = require('@canvas/image'); // @canvas/image can decode jpeg, png, webp * - Uses external library [@canvas/image](https://www.npmjs.com/package/@canvas/image) to decode image
const log = require('@vladmandic/pilogger'); * - 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 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('../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 modelPath = 'model/';
const imageFile = 'demo/sample1.jpg'; const imageFile = 'demo/sample1.jpg';

View File

@ -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 fs = require('fs');
const path = require('path'); const path = require('path');
const log = require('@vladmandic/pilogger'); 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 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('../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; let optionsSSDMobileNet;
const minConfidence = 0.1; const minConfidence = 0.1;
@ -33,6 +38,8 @@ async function getDescriptors(imageFile) {
} }
async function registerImage(inputFile) { 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); const descriptors = await getDescriptors(inputFile);
for (const descriptor of descriptors) { for (const descriptor of descriptors) {
const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(inputFile, [descriptor]); const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(inputFile, [descriptor]);
@ -60,14 +67,18 @@ async function main() {
await initFaceAPI(); await initFaceAPI();
log.info('Input:', process.argv[2]); log.info('Input:', process.argv[2]);
if (fs.statSync(process.argv[2]).isFile()) { 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()) { } else if (fs.statSync(process.argv[2]).isDirectory()) {
const dir = fs.readdirSync(process.argv[2]); 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(); main();

View File

@ -1,14 +1,16 @@
// @ts-nocheck /**
* FaceAPI Demo for NodeJS
* - Used by `node-multiprocess.js`
*/
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const log = require('@vladmandic/pilogger'); const log = require('@vladmandic/pilogger');
// workers actual import tfjs and faceapi modules // 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 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('../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 // options used by faceapi
const modelPathRoot = '../model'; const modelPathRoot = '../model';

View File

@ -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 fs = require('fs');
const path = require('path'); const path = require('path');
const log = require('@vladmandic/pilogger'); // this is my simple logger with few extra features const log = require('@vladmandic/pilogger'); // this is my simple logger with few extra features

View File

@ -1,7 +1,13 @@
/**
* FaceAPI Demo for NodeJS
* - Loads image
* - Outputs results to console
*/
const fs = require('fs'); 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('../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() { async function main() {
await faceapi.nets.ssdMobilenetv1.loadFromDisk('model'); // load models from a specific patch await faceapi.nets.ssdMobilenetv1.loadFromDisk('model'); // load models from a specific patch
@ -19,8 +25,7 @@ async function main() {
.withFaceDescriptors() .withFaceDescriptors()
.withAgeAndGender(); .withAgeAndGender();
faceapi.tf.dispose([decodeT, expandT]); // dispose tensors to avoid memory leaks faceapi.tf.dispose([decodeT, expandT]); // dispose tensors to avoid memory leaks
// eslint-disable-next-line no-console console.log({ result }); // eslint-disable-line no-console
console.log({ result }); // print results
} }
main(); main();

View File

@ -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 fs = require('fs');
const process = require('process'); const process = require('process');
const path = require('path'); const path = require('path');
const log = require('@vladmandic/pilogger'); 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 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('../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 modelPathRoot = '../model';
const imgPathRoot = './demo'; // modify to include your sample images const imgPathRoot = './demo'; // modify to include your sample images
@ -87,11 +93,9 @@ async function main() {
log.header(); log.header();
log.info('FaceAPI single-process test'); 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.setBackend('tensorflow');
await faceapi.tf.enableProdMode();
await faceapi.tf.ENV.set('DEBUG', false);
await faceapi.tf.ready(); await faceapi.tf.ready();
log.state(`Version: TensorFlow/JS ${faceapi.tf?.version_core} FaceAPI ${faceapi.version} Backend: ${faceapi.tf?.getBackend()}`); log.state(`Version: TensorFlow/JS ${faceapi.tf?.version_core} FaceAPI ${faceapi.version} Backend: ${faceapi.tf?.getBackend()}`);

View File

@ -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 // configuration options
const modelPath = '../model/'; // path to model folder that will be loaded using http 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 minScore = 0.2; // minimum score
const maxResults = 5; // maximum number of results to return const maxResults = 5; // maximum number of results to return
let optionsSSDMobileNet; let optionsSSDMobileNet;
@ -17,8 +23,7 @@ function str(json) {
// helper function to print strings to html document as a log // helper function to print strings to html document as a log
function log(...txt) { function log(...txt) {
// eslint-disable-next-line no-console console.log(...txt); // eslint-disable-line no-console
console.log(...txt);
const div = document.getElementById('log'); const div = document.getElementById('log');
if (div) div.innerHTML += `<br>${txt}`; if (div) div.innerHTML += `<br>${txt}`;
} }

View File

@ -41,11 +41,6 @@
"tensorflowjs", "tensorflowjs",
"tfjs" "tfjs"
], ],
"optionalDependencies": {
"@canvas/image": "^1.0.1",
"canvas": "^2.9.3",
"node-fetch": "^3.2.10"
},
"devDependencies": { "devDependencies": {
"@microsoft/api-extractor": "^7.29.3", "@microsoft/api-extractor": "^7.29.3",
"@tensorflow/tfjs": "^3.19.0", "@tensorflow/tfjs": "^3.19.0",
@ -59,10 +54,10 @@
"@tensorflow/tfjs-layers": "^3.19.0", "@tensorflow/tfjs-layers": "^3.19.0",
"@tensorflow/tfjs-node": "^3.19.0", "@tensorflow/tfjs-node": "^3.19.0",
"@tensorflow/tfjs-node-gpu": "^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", "@types/offscreencanvas": "^2019.7.0",
"@typescript-eslint/eslint-plugin": "^5.33.1", "@typescript-eslint/eslint-plugin": "^5.34.0",
"@typescript-eslint/parser": "^5.33.1", "@typescript-eslint/parser": "^5.34.0",
"@vladmandic/build": "^0.7.10", "@vladmandic/build": "^0.7.10",
"@vladmandic/pilogger": "^0.4.6", "@vladmandic/pilogger": "^0.4.6",
"@vladmandic/tfjs": "github:vladmandic/tfjs", "@vladmandic/tfjs": "github:vladmandic/tfjs",

View File

@ -1,4 +1 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable node/no-unpublished-import */
export * from '@tensorflow/tfjs'; export * from '@tensorflow/tfjs';

View File

@ -1,4 +1 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable node/no-unpublished-import */
export * from '@tensorflow/tfjs-node-gpu'; export * from '@tensorflow/tfjs-node-gpu';

View File

@ -1,5 +1,2 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable node/no-unpublished-import */
export * from '@tensorflow/tfjs'; export * from '@tensorflow/tfjs';
export * from '@tensorflow/tfjs-backend-wasm'; export * from '@tensorflow/tfjs-backend-wasm';

View File

@ -1,4 +1 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable node/no-unpublished-import */
export * from '@tensorflow/tfjs-node'; export * from '@tensorflow/tfjs-node';

View File

@ -1,8 +1,6 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
// eslint-disable-next-line import/no-extraneous-dependencies, node/no-unpublished-require
const log = require('@vladmandic/pilogger'); const log = require('@vladmandic/pilogger');
// eslint-disable-next-line import/no-extraneous-dependencies, node/no-unpublished-require
const tf = require('@tensorflow/tfjs-node'); const tf = require('@tensorflow/tfjs-node');
const faceapi = require('../dist/face-api.node.js'); // this is equivalent to '@vladmandic/faceapi' const faceapi = require('../dist/face-api.node.js'); // this is equivalent to '@vladmandic/faceapi'