fix face matcher

pull/97/head
Vladimir Mandic 2021-09-29 09:32:30 -04:00
parent fdddee7101
commit 1b4580dd6e
76 changed files with 238 additions and 274 deletions

View File

@ -9,7 +9,10 @@
## Changelog ## Changelog
### **HEAD -> master** 2021/09/16 mandic00@live.com ### **1.5.4** 2021/09/29 mandic00@live.com
### **origin/master** 2021/09/18 mandic00@live.com
### **1.5.3** 2021/09/16 mandic00@live.com ### **1.5.3** 2021/09/16 mandic00@live.com

View File

@ -9,9 +9,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty; var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __require = typeof require !== "undefined" ? require : (x) => { var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw new Error('Dynamic require of "' + x + '" is not supported'); throw new Error('Dynamic require of "' + x + '" is not supported');
}; });
var __export = (target, all) => { var __export = (target, all) => {
__markAsModule(target); __markAsModule(target);
for (var name in all) for (var name in all)
@ -2148,7 +2152,7 @@ function drawFaceLandmarks(canvasArg, faceLandmarks) {
} }
// package.json // package.json
var version10 = "1.5.3"; var version10 = "1.5.4";
// src/xception/extractParams.ts // src/xception/extractParams.ts
function extractorsFactory2(extractWeights, paramMappings) { function extractorsFactory2(extractWeights, paramMappings) {
@ -4303,21 +4307,17 @@ var FaceMatcher = class {
constructor(inputs, distanceThreshold = 0.6) { constructor(inputs, distanceThreshold = 0.6) {
this._distanceThreshold = distanceThreshold; this._distanceThreshold = distanceThreshold;
const inputArray = Array.isArray(inputs) ? inputs : [inputs]; const inputArray = Array.isArray(inputs) ? inputs : [inputs];
if (!inputArray.length) { if (!inputArray.length)
throw new Error("FaceRecognizer.constructor - expected atleast one input"); throw new Error("FaceRecognizer.constructor - expected atleast one input");
}
let count = 1; let count = 1;
const createUniqueLabel = () => `person ${count++}`; const createUniqueLabel = () => `person ${count++}`;
this._labeledDescriptors = inputArray.map((desc) => { this._labeledDescriptors = inputArray.map((desc) => {
if (desc instanceof LabeledFaceDescriptors) { if (desc instanceof LabeledFaceDescriptors)
return desc; return desc;
} if (desc instanceof Float32Array)
if (desc instanceof Float32Array) {
return new LabeledFaceDescriptors(createUniqueLabel(), [desc]); return new LabeledFaceDescriptors(createUniqueLabel(), [desc]);
} if (desc.descriptor && desc.descriptor instanceof Float32Array)
if (desc.descriptor && desc.descriptor instanceof Float32Array) {
return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]); return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]);
}
throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>"); throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>");
}); });
} }
@ -4335,12 +4335,12 @@ var FaceMatcher = class {
} }
findBestMatch(queryDescriptor) { findBestMatch(queryDescriptor) {
const bestMatch = this.matchDescriptor(queryDescriptor); const bestMatch = this.matchDescriptor(queryDescriptor);
return bestMatch.distance < this.distanceThreshold ? bestMatch : new FaceMatch("unknown", bestMatch.distance); return bestMatch.distance < this._distanceThreshold ? bestMatch : new FaceMatch("unknown", bestMatch.distance);
} }
toJSON() { toJSON() {
return { return {
distanceThreshold: this.distanceThreshold, distanceThreshold: this._distanceThreshold,
labeledDescriptors: this.labeledDescriptors.map((ld) => ld.toJSON()) labeledDescriptors: this._labeledDescriptors.map((ld) => ld.toJSON())
}; };
} }
static fromJSON(json) { static fromJSON(json) {

File diff suppressed because one or more lines are too long

38
dist/face-api.esm.js vendored
View File

@ -6,9 +6,13 @@
var __defProp = Object.defineProperty; var __defProp = Object.defineProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __require = typeof require !== "undefined" ? require : (x) => { var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw new Error('Dynamic require of "' + x + '" is not supported'); throw new Error('Dynamic require of "' + x + '" is not supported');
}; });
var __export = (target, all5) => { var __export = (target, all5) => {
__markAsModule(target); __markAsModule(target);
for (var name in all5) for (var name in all5)
@ -511,9 +515,13 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf; var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty; var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule2 = (target) => __defProp2(target, "__esModule", { value: true }); var __markAsModule2 = (target) => __defProp2(target, "__esModule", { value: true });
var __require2 = typeof __require !== "undefined" ? __require : (x) => { var __require2 = /* @__PURE__ */ ((x) => typeof __require !== "undefined" ? __require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof __require !== "undefined" ? __require : a)[b]
}) : x)(function(x) {
if (typeof __require !== "undefined")
return __require.apply(this, arguments);
throw new Error('Dynamic require of "' + x + '" is not supported'); throw new Error('Dynamic require of "' + x + '" is not supported');
}; });
var __commonJS = (cb, mod4) => function __require22() { var __commonJS = (cb, mod4) => function __require22() {
return mod4 || (0, cb[Object.keys(cb)[0]])((mod4 = { exports: {} }).exports, mod4), mod4.exports; return mod4 || (0, cb[Object.keys(cb)[0]])((mod4 = { exports: {} }).exports, mod4), mod4.exports;
}; };
@ -1357,7 +1365,7 @@ var require_long = __commonJS({
} }
}); });
var require_browser = __commonJS({ var require_browser = __commonJS({
"(disabled):node_modules/.pnpm/node-fetch@2.6.2/node_modules/node-fetch/browser.js"() { "(disabled):node_modules/.pnpm/node-fetch@2.6.5/node_modules/node-fetch/browser.js"() {
} }
}); });
var require_alea = __commonJS({ var require_alea = __commonJS({
@ -62205,7 +62213,7 @@ function drawFaceLandmarks(canvasArg, faceLandmarks) {
} }
// package.json // package.json
var version6 = "1.5.3"; var version6 = "1.5.4";
// src/xception/extractParams.ts // src/xception/extractParams.ts
function extractorsFactory2(extractWeights, paramMappings) { function extractorsFactory2(extractWeights, paramMappings) {
@ -64360,21 +64368,17 @@ var FaceMatcher = class {
constructor(inputs, distanceThreshold = 0.6) { constructor(inputs, distanceThreshold = 0.6) {
this._distanceThreshold = distanceThreshold; this._distanceThreshold = distanceThreshold;
const inputArray = Array.isArray(inputs) ? inputs : [inputs]; const inputArray = Array.isArray(inputs) ? inputs : [inputs];
if (!inputArray.length) { if (!inputArray.length)
throw new Error("FaceRecognizer.constructor - expected atleast one input"); throw new Error("FaceRecognizer.constructor - expected atleast one input");
}
let count2 = 1; let count2 = 1;
const createUniqueLabel = () => `person ${count2++}`; const createUniqueLabel = () => `person ${count2++}`;
this._labeledDescriptors = inputArray.map((desc) => { this._labeledDescriptors = inputArray.map((desc) => {
if (desc instanceof LabeledFaceDescriptors) { if (desc instanceof LabeledFaceDescriptors)
return desc; return desc;
} if (desc instanceof Float32Array)
if (desc instanceof Float32Array) {
return new LabeledFaceDescriptors(createUniqueLabel(), [desc]); return new LabeledFaceDescriptors(createUniqueLabel(), [desc]);
} if (desc.descriptor && desc.descriptor instanceof Float32Array)
if (desc.descriptor && desc.descriptor instanceof Float32Array) {
return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]); return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]);
}
throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>"); throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>");
}); });
} }
@ -64392,12 +64396,12 @@ var FaceMatcher = class {
} }
findBestMatch(queryDescriptor) { findBestMatch(queryDescriptor) {
const bestMatch = this.matchDescriptor(queryDescriptor); const bestMatch = this.matchDescriptor(queryDescriptor);
return bestMatch.distance < this.distanceThreshold ? bestMatch : new FaceMatch("unknown", bestMatch.distance); return bestMatch.distance < this._distanceThreshold ? bestMatch : new FaceMatch("unknown", bestMatch.distance);
} }
toJSON() { toJSON() {
return { return {
distanceThreshold: this.distanceThreshold, distanceThreshold: this._distanceThreshold,
labeledDescriptors: this.labeledDescriptors.map((ld) => ld.toJSON()) labeledDescriptors: this._labeledDescriptors.map((ld) => ld.toJSON())
}; };
} }
static fromJSON(json20) { static fromJSON(json20) {

File diff suppressed because one or more lines are too long

182
dist/face-api.js vendored

File diff suppressed because one or more lines are too long

View File

@ -11,10 +11,7 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf; var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty; var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __require = typeof require !== "undefined" ? require : (x) => { var __commonJS = (cb, mod) => function __require() {
throw new Error('Dynamic require of "' + x + '" is not supported');
};
var __commonJS = (cb, mod) => function __require2() {
return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
}; };
var __export = (target, all) => { var __export = (target, all) => {
@ -44,9 +41,6 @@ var require_tfjs_esm = __commonJS({
var __getProtoOf2 = Object.getPrototypeOf; var __getProtoOf2 = Object.getPrototypeOf;
var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __hasOwnProp2 = Object.prototype.hasOwnProperty;
var __markAsModule2 = (target) => __defProp2(target, "__esModule", { value: true }); var __markAsModule2 = (target) => __defProp2(target, "__esModule", { value: true });
var __require2 = typeof require !== "undefined" ? require : (x) => {
throw new Error('Dynamic require of "' + x + '" is not supported');
};
var __reExport2 = (target, module22, desc) => { var __reExport2 = (target, module22, desc) => {
if (module22 && typeof module22 === "object" || typeof module22 === "function") { if (module22 && typeof module22 === "object" || typeof module22 === "function") {
for (let key of __getOwnPropNames2(module22)) for (let key of __getOwnPropNames2(module22))
@ -2313,7 +2307,7 @@ function drawFaceLandmarks(canvasArg, faceLandmarks) {
} }
// package.json // package.json
var version = "1.5.3"; var version = "1.5.4";
// src/ageGenderNet/AgeGenderNet.ts // src/ageGenderNet/AgeGenderNet.ts
var tf20 = __toModule(require_tfjs_esm()); var tf20 = __toModule(require_tfjs_esm());
@ -4513,21 +4507,17 @@ var FaceMatcher = class {
constructor(inputs, distanceThreshold = 0.6) { constructor(inputs, distanceThreshold = 0.6) {
this._distanceThreshold = distanceThreshold; this._distanceThreshold = distanceThreshold;
const inputArray = Array.isArray(inputs) ? inputs : [inputs]; const inputArray = Array.isArray(inputs) ? inputs : [inputs];
if (!inputArray.length) { if (!inputArray.length)
throw new Error("FaceRecognizer.constructor - expected atleast one input"); throw new Error("FaceRecognizer.constructor - expected atleast one input");
}
let count = 1; let count = 1;
const createUniqueLabel = () => `person ${count++}`; const createUniqueLabel = () => `person ${count++}`;
this._labeledDescriptors = inputArray.map((desc) => { this._labeledDescriptors = inputArray.map((desc) => {
if (desc instanceof LabeledFaceDescriptors) { if (desc instanceof LabeledFaceDescriptors)
return desc; return desc;
} if (desc instanceof Float32Array)
if (desc instanceof Float32Array) {
return new LabeledFaceDescriptors(createUniqueLabel(), [desc]); return new LabeledFaceDescriptors(createUniqueLabel(), [desc]);
} if (desc.descriptor && desc.descriptor instanceof Float32Array)
if (desc.descriptor && desc.descriptor instanceof Float32Array) {
return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]); return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]);
}
throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>"); throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>");
}); });
} }
@ -4545,12 +4535,12 @@ var FaceMatcher = class {
} }
findBestMatch(queryDescriptor) { findBestMatch(queryDescriptor) {
const bestMatch = this.matchDescriptor(queryDescriptor); const bestMatch = this.matchDescriptor(queryDescriptor);
return bestMatch.distance < this.distanceThreshold ? bestMatch : new FaceMatch("unknown", bestMatch.distance); return bestMatch.distance < this._distanceThreshold ? bestMatch : new FaceMatch("unknown", bestMatch.distance);
} }
toJSON() { toJSON() {
return { return {
distanceThreshold: this.distanceThreshold, distanceThreshold: this._distanceThreshold,
labeledDescriptors: this.labeledDescriptors.map((ld) => ld.toJSON()) labeledDescriptors: this._labeledDescriptors.map((ld) => ld.toJSON())
}; };
} }
static fromJSON(json) { static fromJSON(json) {

28
dist/face-api.node.js vendored
View File

@ -11,10 +11,7 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf; var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty; var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __require = typeof require !== "undefined" ? require : (x) => { var __commonJS = (cb, mod) => function __require() {
throw new Error('Dynamic require of "' + x + '" is not supported');
};
var __commonJS = (cb, mod) => function __require2() {
return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
}; };
var __export = (target, all) => { var __export = (target, all) => {
@ -44,9 +41,6 @@ var require_tfjs_esm = __commonJS({
var __getProtoOf2 = Object.getPrototypeOf; var __getProtoOf2 = Object.getPrototypeOf;
var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __hasOwnProp2 = Object.prototype.hasOwnProperty;
var __markAsModule2 = (target) => __defProp2(target, "__esModule", { value: true }); var __markAsModule2 = (target) => __defProp2(target, "__esModule", { value: true });
var __require2 = typeof require !== "undefined" ? require : (x) => {
throw new Error('Dynamic require of "' + x + '" is not supported');
};
var __reExport2 = (target, module22, desc) => { var __reExport2 = (target, module22, desc) => {
if (module22 && typeof module22 === "object" || typeof module22 === "function") { if (module22 && typeof module22 === "object" || typeof module22 === "function") {
for (let key of __getOwnPropNames2(module22)) for (let key of __getOwnPropNames2(module22))
@ -2313,7 +2307,7 @@ function drawFaceLandmarks(canvasArg, faceLandmarks) {
} }
// package.json // package.json
var version = "1.5.3"; var version = "1.5.4";
// src/ageGenderNet/AgeGenderNet.ts // src/ageGenderNet/AgeGenderNet.ts
var tf20 = __toModule(require_tfjs_esm()); var tf20 = __toModule(require_tfjs_esm());
@ -4513,21 +4507,17 @@ var FaceMatcher = class {
constructor(inputs, distanceThreshold = 0.6) { constructor(inputs, distanceThreshold = 0.6) {
this._distanceThreshold = distanceThreshold; this._distanceThreshold = distanceThreshold;
const inputArray = Array.isArray(inputs) ? inputs : [inputs]; const inputArray = Array.isArray(inputs) ? inputs : [inputs];
if (!inputArray.length) { if (!inputArray.length)
throw new Error("FaceRecognizer.constructor - expected atleast one input"); throw new Error("FaceRecognizer.constructor - expected atleast one input");
}
let count = 1; let count = 1;
const createUniqueLabel = () => `person ${count++}`; const createUniqueLabel = () => `person ${count++}`;
this._labeledDescriptors = inputArray.map((desc) => { this._labeledDescriptors = inputArray.map((desc) => {
if (desc instanceof LabeledFaceDescriptors) { if (desc instanceof LabeledFaceDescriptors)
return desc; return desc;
} if (desc instanceof Float32Array)
if (desc instanceof Float32Array) {
return new LabeledFaceDescriptors(createUniqueLabel(), [desc]); return new LabeledFaceDescriptors(createUniqueLabel(), [desc]);
} if (desc.descriptor && desc.descriptor instanceof Float32Array)
if (desc.descriptor && desc.descriptor instanceof Float32Array) {
return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]); return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]);
}
throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>"); throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>");
}); });
} }
@ -4545,12 +4535,12 @@ var FaceMatcher = class {
} }
findBestMatch(queryDescriptor) { findBestMatch(queryDescriptor) {
const bestMatch = this.matchDescriptor(queryDescriptor); const bestMatch = this.matchDescriptor(queryDescriptor);
return bestMatch.distance < this.distanceThreshold ? bestMatch : new FaceMatch("unknown", bestMatch.distance); return bestMatch.distance < this._distanceThreshold ? bestMatch : new FaceMatch("unknown", bestMatch.distance);
} }
toJSON() { toJSON() {
return { return {
distanceThreshold: this.distanceThreshold, distanceThreshold: this._distanceThreshold,
labeledDescriptors: this.labeledDescriptors.map((ld) => ld.toJSON()) labeledDescriptors: this._labeledDescriptors.map((ld) => ld.toJSON())
}; };
} }
static fromJSON(json) { static fromJSON(json) {

12
dist/tfjs.esm.js vendored
View File

@ -11,9 +11,13 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf; var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty; var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __require = typeof require !== "undefined" ? require : (x) => { var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw new Error('Dynamic require of "' + x + '" is not supported'); throw new Error('Dynamic require of "' + x + '" is not supported');
}; });
var __commonJS = (cb, mod4) => function __require2() { var __commonJS = (cb, mod4) => function __require2() {
return mod4 || (0, cb[Object.keys(cb)[0]])((mod4 = { exports: {} }).exports, mod4), mod4.exports; return mod4 || (0, cb[Object.keys(cb)[0]])((mod4 = { exports: {} }).exports, mod4), mod4.exports;
}; };
@ -859,9 +863,9 @@ var require_long = __commonJS({
} }
}); });
// (disabled):node_modules/.pnpm/node-fetch@2.6.2/node_modules/node-fetch/browser.js // (disabled):node_modules/.pnpm/node-fetch@2.6.5/node_modules/node-fetch/browser.js
var require_browser = __commonJS({ var require_browser = __commonJS({
"(disabled):node_modules/.pnpm/node-fetch@2.6.2/node_modules/node-fetch/browser.js"() { "(disabled):node_modules/.pnpm/node-fetch@2.6.5/node_modules/node-fetch/browser.js"() {
} }
}); });

File diff suppressed because one or more lines are too long

View File

@ -7,7 +7,6 @@ export interface IFaceMatch {
export class FaceMatch implements IFaceMatch { export class FaceMatch implements IFaceMatch {
private _label: string private _label: string
private _distance: number private _distance: number
constructor(label: string, distance: number) { constructor(label: string, distance: number) {

View File

@ -5,37 +5,18 @@ import { WithFaceDescriptor } from '../factories/index';
export class FaceMatcher { export class FaceMatcher {
private _labeledDescriptors: LabeledFaceDescriptors[] private _labeledDescriptors: LabeledFaceDescriptors[]
private _distanceThreshold: number private _distanceThreshold: number
constructor( constructor(inputs: LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>, distanceThreshold = 0.6) {
inputs: LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>,
distanceThreshold = 0.6,
) {
this._distanceThreshold = distanceThreshold; this._distanceThreshold = distanceThreshold;
const inputArray = Array.isArray(inputs) ? inputs : [inputs]; const inputArray = Array.isArray(inputs) ? inputs : [inputs];
if (!inputArray.length) throw new Error('FaceRecognizer.constructor - expected atleast one input');
if (!inputArray.length) {
throw new Error('FaceRecognizer.constructor - expected atleast one input');
}
let count = 1; let count = 1;
const createUniqueLabel = () => `person ${count++}`; const createUniqueLabel = () => `person ${count++}`;
this._labeledDescriptors = inputArray.map((desc) => { this._labeledDescriptors = inputArray.map((desc) => {
if (desc instanceof LabeledFaceDescriptors) { if (desc instanceof LabeledFaceDescriptors) return desc;
return desc; if (desc instanceof Float32Array) return new LabeledFaceDescriptors(createUniqueLabel(), [desc]);
} if (desc.descriptor && desc.descriptor instanceof Float32Array) return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]);
if (desc instanceof Float32Array) {
return new LabeledFaceDescriptors(createUniqueLabel(), [desc]);
}
if (desc.descriptor && desc.descriptor instanceof Float32Array) {
return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]);
}
throw new Error('FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>'); throw new Error('FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>');
}); });
} }
@ -47,36 +28,29 @@ export class FaceMatcher {
public computeMeanDistance(queryDescriptor: Float32Array, descriptors: Float32Array[]): number { public computeMeanDistance(queryDescriptor: Float32Array, descriptors: Float32Array[]): number {
return descriptors return descriptors
.map((d) => euclideanDistance(d, queryDescriptor)) .map((d) => euclideanDistance(d, queryDescriptor))
.reduce((d1, d2) => d1 + d2, 0) .reduce((d1, d2) => d1 + d2, 0) / (descriptors.length || 1);
/ (descriptors.length || 1);
} }
public matchDescriptor(queryDescriptor: Float32Array): FaceMatch { public matchDescriptor(queryDescriptor: Float32Array): FaceMatch {
return this.labeledDescriptors return this.labeledDescriptors
.map(({ descriptors, label }) => new FaceMatch( .map(({ descriptors, label }) => new FaceMatch(label, this.computeMeanDistance(queryDescriptor, descriptors)))
label,
this.computeMeanDistance(queryDescriptor, descriptors),
))
.reduce((best, curr) => (best.distance < curr.distance ? best : curr)); .reduce((best, curr) => (best.distance < curr.distance ? best : curr));
} }
public findBestMatch(queryDescriptor: Float32Array): FaceMatch { public findBestMatch(queryDescriptor: Float32Array): FaceMatch {
const bestMatch = this.matchDescriptor(queryDescriptor); const bestMatch = this.matchDescriptor(queryDescriptor);
return bestMatch.distance < this.distanceThreshold return bestMatch.distance < this._distanceThreshold ? bestMatch : new FaceMatch('unknown', bestMatch.distance);
? bestMatch
: new FaceMatch('unknown', bestMatch.distance);
} }
public toJSON(): any { public toJSON(): any {
return { return {
distanceThreshold: this.distanceThreshold, distanceThreshold: this._distanceThreshold,
labeledDescriptors: this.labeledDescriptors.map((ld) => ld.toJSON()), labeledDescriptors: this._labeledDescriptors.map((ld) => ld.toJSON()),
}; };
} }
public static fromJSON(json: any): FaceMatcher { public static fromJSON(json: any): FaceMatcher {
const labeledDescriptors = json.labeledDescriptors const labeledDescriptors = json.labeledDescriptors.map((ld: any) => LabeledFaceDescriptors.fromJSON(ld));
.map((ld: any) => LabeledFaceDescriptors.fromJSON(ld));
return new FaceMatcher(labeledDescriptors, json.distanceThreshold); return new FaceMatcher(labeledDescriptors, json.distanceThreshold);
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long