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",