From 7c02d78df90c773f0f04d1278771d87aa41692cb Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Sun, 11 Oct 2020 12:41:17 -0400 Subject: [PATCH] major update --- README.md | 108 +- build/package.json | 21 +- build/src/NeuralNetwork.d.ts.map | 2 +- build/src/NeuralNetwork.js.map | 2 +- build/src/Platform.d.ts | 8 + build/src/Platform.d.ts.map | 1 + build/src/Platform.js | 21 + build/src/Platform.js.map | 1 + build/src/index.d.ts | 4 +- build/src/index.js | 7 +- build/src/index.js.map | 2 +- dist/face-api.cjs.js | 4345 ---------------------------- dist/face-api.cjs.js.map | 7 - dist/face-api.esm.js | 64 +- dist/face-api.esm.js.map | 6 +- dist/face-api.iife.js | 4350 ---------------------------- dist/face-api.iife.js.map | 7 - dist/face-api.js | 3976 ++++++++++++++++++++++++++ dist/face-api.js.map | 7 + dist/face-api.min.js | 2 - dist/face-api.min.js.map | 7 - dist/face-api.node.js | 4534 ------------------------------ dist/face-api.node.js.map | 7 - example/index.html | 12 +- package-lock.json | 18 +- package.json | 23 +- src/NeuralNetwork.ts | 1 - src/Platform.ts | 25 + src/index.ts | 7 +- tsconfig.json | 2 +- 30 files changed, 4201 insertions(+), 13376 deletions(-) create mode 100644 build/src/Platform.d.ts create mode 100644 build/src/Platform.d.ts.map create mode 100644 build/src/Platform.js create mode 100644 build/src/Platform.js.map delete mode 100644 dist/face-api.cjs.js delete mode 100644 dist/face-api.cjs.js.map delete mode 100644 dist/face-api.iife.js delete mode 100644 dist/face-api.iife.js.map create mode 100644 dist/face-api.js create mode 100644 dist/face-api.js.map delete mode 100644 dist/face-api.min.js delete mode 100644 dist/face-api.min.js.map delete mode 100644 dist/face-api.node.js delete mode 100644 dist/face-api.node.js.map create mode 100644 src/Platform.ts diff --git a/README.md b/README.md index 67a191a..0d76c48 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ ## Note This is updated **face-api.js** with latest available TensorFlow/JS as the original face-api.js is not compatible with **tfjs 2.0+**. -Currently based on **TFJS-Core 2.4.0**. Forked from **face-api.js** version **0.22.2** released on March 22nd, 2020 @@ -17,12 +16,13 @@ Forked from **face-api.js** version **0.22.2** released on March 22nd, 2020 - Compatible with TensorFlow/JS 2.0+ - Updated type casting for TypeScript type checking - Removed unnecesary package dependencies (karma, jasmine, etc.) -- Typescript build process now targets ES2017 and instead of dual ES5/ES6 +- Typescript build process now targets ES2018 and instead of dual ES5/ES6 - Browser bundle process uses ESBuild instead of Rollup - New TensorFlow/JS dependencies since backends were removed from @tensorflow/tfjs-core - Updated mobileNetv1 model due to batchNorm() dependency - Fully tree shakable when imported as an ESM module -- Added `version` class that returns JSON objecgt with version of FaceAPI as well as linked TFJS +- Added `version` class that returns JSON object with version of FaceAPI as well as linked TFJS +- Added calls for `setPlatform` to automatically prepare TFJS in browser - Removed following models as they are either obsolete or non-functional with tfjs 2.0+ - mtcnn: Mostly obsolete - tinyYolov2: Non-functional since weights are missing @@ -32,48 +32,63 @@ Due to reduced code and changed build process, resulting bundle is about **>5x s ## Installation -**Imporant!**: This version of **face-api** does not embedd full version of **TensorFlow/JS (tfjs)** to keep package as small as possible (322KB minified), enable dynamic loading of different tfjs backends as well as to enable reusability of tfjs for different purposes. +There are several ways to use Face-API: -*Load tfjs explicitly before loading face-api.* -*Note: package `@tensorflow/tfjs` is bundle, if you want to keep your project small, import `@tensorflow/tfjs-core` plus a specific backend such as `@tensorflow/tfjs-backend-cpu`, `@tensorflow/tfjs-backend-webgl` or `@tensorflow/tfjs-node`* +### IIFE script + *Size: 936KB minified* -For example as a script: + This is simplest way for usage within Browser as it includes full version of TensorFlow/JS prepackaged with no external dependencies. + Simply include this in your `HTML` file and it's ready to use. -```html - - - or - -``` + ```html + - + + @@ -27,7 +27,7 @@ // helper function to pretty-print json object to string function str(json) { let text = ''; - text += JSON.stringify(json).replace(/{|}|"|\[|\]/g, '').replace(/,/g, ', '); + text += json ? JSON.stringify(json).replace(/{|}|"|\[|\]/g, '').replace(/,/g, ', ') : ''; text += ''; return text; } @@ -120,11 +120,15 @@ async function main() { // initialize tfjs log('FaceAPI Test'); + window.tf = faceapi.tf; await faceapi.tf.setBackend('webgl'); await faceapi.tf.enableProdMode(); await faceapi.tf.ENV.set('DEBUG', false); + await faceapi.tf.ready(); + // check version - log(`Version: ${str(faceapi.version)}`); + log(`Version: TensorFlow/JS ${str(faceapi.tf?.version_core || '(not loaded)')} FaceAPI ${str(faceapi?.version || '(not loaded)')} Backend: ${str(faceapi.tf?.getBackend() || '(not loaded)')}`); + log(`Flags: ${JSON.stringify(faceapi.tf.ENV.flags)}`); // load face-api models log('Loading FaceAPI models'); diff --git a/package-lock.json b/package-lock.json index 36399ca..ab90c4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -77,9 +77,9 @@ "integrity": "sha512-nU9WNSGpEU6GzKo5bvJBMa/OZRe1bR5Z2W6T0XiEY8CBiPNS+oJFJNm0NY8kQj/WnDS0Hfue38P46q7gV/9XMA==" }, "@types/node": { - "version": "14.11.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.7.tgz", - "integrity": "sha512-hSEXknS4KiayUdZ7401J/T6eykXHJkDEipnyQMJ4/GstK4kWjbHnwXlcpvIWfPKiEH1JU96DkbzJ1nHRmpmKLw==" + "version": "14.11.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.8.tgz", + "integrity": "sha512-KPcKqKm5UKDkaYPTuXSx8wEP7vE9GnuaXIZKijwRYcePpZFDVuy2a57LarFKiORbHOuTOOwYzxVxcUzsh2P2Pw==" }, "@types/node-fetch": { "version": "2.5.7", @@ -436,15 +436,15 @@ } }, "tslib": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.2.tgz", - "integrity": "sha512-wAH28hcEKwna96/UacuWaVspVLkg4x1aDM9JlzqaQTOFczCktkVAb5fmXChgandR1EraDPs2w8P+ozM+oafwxg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", "dev": true }, "typescript": { - "version": "4.1.0-dev.20201008", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.0-dev.20201008.tgz", - "integrity": "sha512-+g2TfvYueD60iu2YXz5czsDRdY4M/h9RvmwrorTTNmnTQaUOeb7spT4EyHa1g5TjhqHa/8+lCgCdPkuEQqg9WA==", + "version": "4.1.0-dev.20201011", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.0-dev.20201011.tgz", + "integrity": "sha512-+Lfj2Q+dXFAJbfB1jQQRlhTssgl0CQVo8a+CNzlNXsnC1cN1yoH40wkEjWd6uB8NGkamxKda1xrEb2miJtpP5g==", "dev": true }, "wrap-ansi": { diff --git a/package.json b/package.json index 98216cb..71cae06 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,18 @@ { "name": "@vladmandic/face-api", - "version": "0.5.3", + "version": "0.6.0", "description": "JavaScript module for Face Detection and Face Recognition Using Tensorflow/JS", "main": "build/src/index.js", - "browser": "dist/face-api.esm.js", - "typings": "./build/src/index.d.ts", + "browser": "dist/face-api.js", + "typings": "build/src/index.d.ts", "engines": { "node": ">=12.0.0" }, "type": "module", "scripts": { - "compile": "tsc", - "clean": "rimraf build/ dist/", - "cjs": "esbuild --bundle --outfile=./dist/face-api.cjs.js --target=esnext --platform=browser --format=cjs --sourcemap --external:@tensorflow/tfjs --log-level=error --tsconfig=./tsconfig.json build/src/index.js", - "node": "esbuild --bundle --outfile=./dist/face-api.node.js --target=esnext --platform=node --format=esm --sourcemap --external:@tensorflow/tfjs --log-level=error --tsconfig=./tsconfig.json build/src/index.js", - "esm": "esbuild --bundle --outfile=./dist/face-api.esm.js --target=esnext --platform=browser --format=esm --sourcemap --external:@tensorflow/tfjs --log-level=error --tsconfig=./tsconfig.json build/src/index.js", - "iife": "esbuild --bundle --outfile=./dist/face-api.iife.js --target=esnext --platform=browser --format=iife --global-name=faceapi --sourcemap --external:@tensorflow/tfjs --log-level=error --tsconfig=./tsconfig.json build/src/index.js", - "minify": "esbuild --bundle --outfile=./dist/face-api.min.js --target=esnext --platform=browser --format=iife --sourcemap --global-name=faceapi --external:@tensorflow/tfjs --log-level=error --minify --tsconfig=./tsconfig.json build/src/index.js", - "build": "npm run clean && npm run compile && npm run cjs && npm run esm && npm run iife && npm run node && npm run minify" + "build-esm": "esbuild --bundle --format=esm --target=esnext --platform=browser --sourcemap --outfile=./dist/face-api.esm.js --external:@tensorflow/tfjs --log-level=error --tsconfig=./tsconfig.json build/src/index.js", + "build-iife": "esbuild --bundle --format=iife --target=esnext --platform=browser --sourcemap --outfile=./dist/face-api.js --global-name=faceapi --minify --log-level=error --tsconfig=./tsconfig.json build/src/index.js", + "build": "rimraf build/ dist/ && tsc && npm run build-esm && npm run build-iife" }, "keywords": [ "tensorflow", @@ -45,11 +40,11 @@ "@tensorflow/tfjs": "^2.6.0" }, "devDependencies": { - "@types/node": "^14.11.7", + "@types/node": "^14.11.8", "esbuild": "^0.6.34", "rimraf": "^3.0.2", "ts-node": "^9.0.0", - "tslib": "^2.0.2", - "typescript": "^4.1.0-dev.20201008" + "tslib": "^2.0.3", + "typescript": "^4.1.0-dev.20201011" } } diff --git a/src/NeuralNetwork.ts b/src/NeuralNetwork.ts index b6cfd3a..d433741 100644 --- a/src/NeuralNetwork.ts +++ b/src/NeuralNetwork.ts @@ -114,7 +114,6 @@ export abstract class NeuralNetwork { filePaths.map(filePath => readFile(filePath).then(buf => buf.buffer)) ) const loadWeights = tf.io.weightsLoaderFactory(fetchWeightsFromDisk) - const manifest = JSON.parse((await readFile(manifestUri)).toString()) const weightMap = await loadWeights(manifest, modelBaseUri) diff --git a/src/Platform.ts b/src/Platform.ts new file mode 100644 index 0000000..742d73f --- /dev/null +++ b/src/Platform.ts @@ -0,0 +1,25 @@ +export class PlatformBrowser { + private textEncoder: TextEncoder; + + fetch(path: string, init?: RequestInit): Promise { + return fetch(path, init); + } + + now(): number { + return performance.now(); + } + + encode(text: string, encoding: string): Uint8Array { + if (encoding !== 'utf-8' && encoding !== 'utf8') { + throw new Error( + `Browser's encoder only supports utf-8, but got ${encoding}`); + } + if (this.textEncoder == null) { + this.textEncoder = new TextEncoder(); + } + return this.textEncoder.encode(text); + } + decode(bytes: Uint8Array, encoding: string): string { + return new TextDecoder(encoding).decode(bytes); + } +} diff --git a/src/index.ts b/src/index.ts index b540da3..1dfacdb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,6 +24,9 @@ export * from './NeuralNetwork'; export * from './resizeResults'; import * as pkg from '../package.json'; -const node = typeof process !== 'undefined' ? process.version : false -const browser = typeof navigator !== 'undefined' ? navigator.userAgent : false +const node = (typeof process !== 'undefined'); +const browser = (typeof navigator !== 'undefined') && (typeof navigator.userAgent !== 'undefined'); export const version = { faceapi: pkg.version, node, browser }; + +import {PlatformBrowser} from './Platform'; +if (!tf.env().platform && tf.env().get('IS_BROWSER')) tf.env().setPlatform('browser', new PlatformBrowser); diff --git a/tsconfig.json b/tsconfig.json index f3bec64..a07a2d1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "lib": ["es2018", "dom"], - "module": "es2020", + "module": "esnext", "moduleResolution": "node", "outDir": "build", "target": "es2018",