added pre-compiled build

pull/13/head
Vladimir Mandic 2020-08-18 08:04:33 -04:00
parent c03673f635
commit b1794ece54
463 changed files with 5765 additions and 1 deletions

1
.gitignore vendored
View File

@ -1,2 +1 @@
node_modules
build

44
build/NeuralNetwork.d.ts vendored Normal file
View File

@ -0,0 +1,44 @@
import * as tf from '@tensorflow/tfjs-core';
import { ParamMapping } from './common';
export declare abstract class NeuralNetwork<TNetParams> {
protected _name: string;
protected _params: TNetParams | undefined;
protected _paramMappings: ParamMapping[];
constructor(_name: string);
get params(): TNetParams | undefined;
get paramMappings(): ParamMapping[];
get isLoaded(): boolean;
getParamFromPath(paramPath: string): tf.Tensor;
reassignParamFromPath(paramPath: string, tensor: tf.Tensor): void;
getParamList(): {
path: string;
tensor: tf.Tensor<tf.Rank>;
}[];
getTrainableParams(): {
path: string;
tensor: tf.Tensor<tf.Rank>;
}[];
getFrozenParams(): {
path: string;
tensor: tf.Tensor<tf.Rank>;
}[];
variable(): void;
freeze(): void;
dispose(throwOnRedispose?: boolean): void;
serializeParams(): Float32Array;
load(weightsOrUrl: Float32Array | string | undefined): Promise<void>;
loadFromUri(uri: string | undefined): Promise<void>;
loadFromDisk(filePath: string | undefined): Promise<void>;
loadFromWeightMap(weightMap: tf.NamedTensorMap): void;
extractWeights(weights: Float32Array): void;
private traversePropertyPath;
protected abstract getDefaultModelName(): string;
protected abstract extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap): {
params: TNetParams;
paramMappings: ParamMapping[];
};
protected abstract extractParams(weights: Float32Array): {
params: TNetParams;
paramMappings: ParamMapping[];
};
}

114
build/NeuralNetwork.js Normal file
View File

@ -0,0 +1,114 @@
import * as tf from '@tensorflow/tfjs-core';
import { getModelUris } from './common/getModelUris';
import { loadWeightMap } from './dom';
import { env } from './env';
export class NeuralNetwork {
constructor(_name) {
this._name = _name;
this._params = undefined;
this._paramMappings = [];
}
get params() { return this._params; }
get paramMappings() { return this._paramMappings; }
get isLoaded() { return !!this.params; }
getParamFromPath(paramPath) {
const { obj, objProp } = this.traversePropertyPath(paramPath);
return obj[objProp];
}
reassignParamFromPath(paramPath, tensor) {
const { obj, objProp } = this.traversePropertyPath(paramPath);
obj[objProp].dispose();
obj[objProp] = tensor;
}
getParamList() {
return this._paramMappings.map(({ paramPath }) => ({
path: paramPath,
tensor: this.getParamFromPath(paramPath)
}));
}
getTrainableParams() {
return this.getParamList().filter(param => param.tensor instanceof tf.Variable);
}
getFrozenParams() {
return this.getParamList().filter(param => !(param.tensor instanceof tf.Variable));
}
variable() {
this.getFrozenParams().forEach(({ path, tensor }) => {
this.reassignParamFromPath(path, tensor.variable());
});
}
freeze() {
this.getTrainableParams().forEach(({ path, tensor: variable }) => {
const tensor = tf.tensor(variable.dataSync());
variable.dispose();
this.reassignParamFromPath(path, tensor);
});
}
dispose(throwOnRedispose = true) {
this.getParamList().forEach(param => {
if (throwOnRedispose && param.tensor.isDisposed) {
throw new Error(`param tensor has already been disposed for path ${param.path}`);
}
param.tensor.dispose();
});
this._params = undefined;
}
serializeParams() {
return new Float32Array(this.getParamList()
.map(({ tensor }) => Array.from(tensor.dataSync()))
.reduce((flat, arr) => flat.concat(arr)));
}
async load(weightsOrUrl) {
if (weightsOrUrl instanceof Float32Array) {
this.extractWeights(weightsOrUrl);
return;
}
await this.loadFromUri(weightsOrUrl);
}
async loadFromUri(uri) {
if (uri && typeof uri !== 'string') {
throw new Error(`${this._name}.loadFromUri - expected model uri`);
}
const weightMap = await loadWeightMap(uri, this.getDefaultModelName());
this.loadFromWeightMap(weightMap);
}
async loadFromDisk(filePath) {
if (filePath && typeof filePath !== 'string') {
throw new Error(`${this._name}.loadFromDisk - expected model file path`);
}
const { readFile } = env.getEnv();
const { manifestUri, modelBaseUri } = getModelUris(filePath, this.getDefaultModelName());
const fetchWeightsFromDisk = (filePaths) => Promise.all(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);
this.loadFromWeightMap(weightMap);
}
loadFromWeightMap(weightMap) {
const { paramMappings, params } = this.extractParamsFromWeigthMap(weightMap);
this._paramMappings = paramMappings;
this._params = params;
}
extractWeights(weights) {
const { paramMappings, params } = this.extractParams(weights);
this._paramMappings = paramMappings;
this._params = params;
}
traversePropertyPath(paramPath) {
if (!this.params) {
throw new Error(`traversePropertyPath - model has no loaded params`);
}
const result = paramPath.split('/').reduce((res, objProp) => {
if (!res.nextObj.hasOwnProperty(objProp)) {
throw new Error(`traversePropertyPath - object does not have property ${objProp}, for path ${paramPath}`);
}
return { obj: res.nextObj, objProp, nextObj: res.nextObj[objProp] };
}, { nextObj: this.params });
const { obj, objProp } = result;
if (!obj || !objProp || !(obj[objProp] instanceof tf.Tensor)) {
throw new Error(`traversePropertyPath - parameter is not a tensor, for path ${paramPath}`);
}
return { obj, objProp };
}
}
//# sourceMappingURL=NeuralNetwork.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"NeuralNetwork.js","sourceRoot":"","sources":["../src/NeuralNetwork.ts"],"names":[],"mappings":"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"}

29
build/ageGenderNet/AgeGenderNet.d.ts vendored Normal file
View File

@ -0,0 +1,29 @@
import * as tf from '@tensorflow/tfjs-core';
import { TinyXception } from '../xception/TinyXception';
import { AgeAndGenderPrediction, NetOutput, NetParams } from './types';
import { NeuralNetwork } from '../NeuralNetwork';
import { NetInput, TNetInput } from '../dom';
export declare class AgeGenderNet extends NeuralNetwork<NetParams> {
private _faceFeatureExtractor;
constructor(faceFeatureExtractor?: TinyXception);
get faceFeatureExtractor(): TinyXception;
runNet(input: NetInput | tf.Tensor4D): NetOutput;
forwardInput(input: NetInput | tf.Tensor4D): NetOutput;
forward(input: TNetInput): Promise<NetOutput>;
predictAgeAndGender(input: TNetInput): Promise<AgeAndGenderPrediction | AgeAndGenderPrediction[]>;
protected getDefaultModelName(): string;
dispose(throwOnRedispose?: boolean): void;
loadClassifierParams(weights: Float32Array): void;
extractClassifierParams(weights: Float32Array): {
params: NetParams;
paramMappings: import("../common").ParamMapping[];
};
protected extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap): {
params: NetParams;
paramMappings: import("../common").ParamMapping[];
};
protected extractParams(weights: Float32Array): {
params: NetParams;
paramMappings: import("../common").ParamMapping[];
};
}

View File

@ -0,0 +1,95 @@
import * as tf from '@tensorflow/tfjs-core';
import { fullyConnectedLayer } from '../common/fullyConnectedLayer';
import { seperateWeightMaps } from '../faceProcessor/util';
import { TinyXception } from '../xception/TinyXception';
import { extractParams } from './extractParams';
import { extractParamsFromWeigthMap } from './extractParamsFromWeigthMap';
import { Gender } from './types';
import { NeuralNetwork } from '../NeuralNetwork';
import { NetInput, toNetInput } from '../dom';
export class AgeGenderNet extends NeuralNetwork {
constructor(faceFeatureExtractor = new TinyXception(2)) {
super('AgeGenderNet');
this._faceFeatureExtractor = faceFeatureExtractor;
}
get faceFeatureExtractor() {
return this._faceFeatureExtractor;
}
runNet(input) {
const { params } = this;
if (!params) {
throw new Error(`${this._name} - load model before inference`);
}
return tf.tidy(() => {
const bottleneckFeatures = input instanceof NetInput
? this.faceFeatureExtractor.forwardInput(input)
: input;
const pooled = tf.avgPool(bottleneckFeatures, [7, 7], [2, 2], 'valid').as2D(bottleneckFeatures.shape[0], -1);
const age = fullyConnectedLayer(pooled, params.fc.age).as1D();
const gender = fullyConnectedLayer(pooled, params.fc.gender);
return { age, gender };
});
}
forwardInput(input) {
return tf.tidy(() => {
const { age, gender } = this.runNet(input);
return { age, gender: tf.softmax(gender) };
});
}
async forward(input) {
return this.forwardInput(await toNetInput(input));
}
async predictAgeAndGender(input) {
const netInput = await toNetInput(input);
const out = await this.forwardInput(netInput);
const ages = tf.unstack(out.age);
const genders = tf.unstack(out.gender);
const ageAndGenderTensors = ages.map((ageTensor, i) => ({
ageTensor,
genderTensor: genders[i]
}));
const predictionsByBatch = await Promise.all(ageAndGenderTensors.map(async ({ ageTensor, genderTensor }) => {
const age = (await ageTensor.data())[0];
const probMale = (await genderTensor.data())[0];
const isMale = probMale > 0.5;
const gender = isMale ? Gender.MALE : Gender.FEMALE;
const genderProbability = isMale ? probMale : (1 - probMale);
ageTensor.dispose();
genderTensor.dispose();
return { age, gender, genderProbability };
}));
out.age.dispose();
out.gender.dispose();
return netInput.isBatchInput
? predictionsByBatch
: predictionsByBatch[0];
}
getDefaultModelName() {
return 'age_gender_model';
}
dispose(throwOnRedispose = true) {
this.faceFeatureExtractor.dispose(throwOnRedispose);
super.dispose(throwOnRedispose);
}
loadClassifierParams(weights) {
const { params, paramMappings } = this.extractClassifierParams(weights);
this._params = params;
this._paramMappings = paramMappings;
}
extractClassifierParams(weights) {
return extractParams(weights);
}
extractParamsFromWeigthMap(weightMap) {
const { featureExtractorMap, classifierMap } = seperateWeightMaps(weightMap);
this.faceFeatureExtractor.loadFromWeightMap(featureExtractorMap);
return extractParamsFromWeigthMap(classifierMap);
}
extractParams(weights) {
const classifierWeightSize = (512 * 1 + 1) + (512 * 2 + 2);
const featureExtractorWeights = weights.slice(0, weights.length - classifierWeightSize);
const classifierWeights = weights.slice(weights.length - classifierWeightSize);
this.faceFeatureExtractor.extractWeights(featureExtractorWeights);
return this.extractClassifierParams(classifierWeights);
}
}
//# sourceMappingURL=AgeGenderNet.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"AgeGenderNet.js","sourceRoot":"","sources":["../../src/ageGenderNet/AgeGenderNet.ts"],"names":[],"mappings":"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"}

6
build/ageGenderNet/extractParams.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
import { ParamMapping } from '../common';
import { NetParams } from './types';
export declare function extractParams(weights: Float32Array): {
params: NetParams;
paramMappings: ParamMapping[];
};

View File

@ -0,0 +1,16 @@
import { extractFCParamsFactory, extractWeightsFactory } from '../common';
export function extractParams(weights) {
const paramMappings = [];
const { extractWeights, getRemainingWeights } = extractWeightsFactory(weights);
const extractFCParams = extractFCParamsFactory(extractWeights, paramMappings);
const age = extractFCParams(512, 1, 'fc/age');
const gender = extractFCParams(512, 2, 'fc/gender');
if (getRemainingWeights().length !== 0) {
throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`);
}
return {
paramMappings,
params: { fc: { age, gender } }
};
}
//# sourceMappingURL=extractParams.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"extractParams.js","sourceRoot":"","sources":["../../src/ageGenderNet/extractParams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAgB,MAAM,WAAW,CAAC;AAGxF,MAAM,UAAU,aAAa,CAAC,OAAqB;IAEjD,MAAM,aAAa,GAAmB,EAAE,CAAA;IAExC,MAAM,EACJ,cAAc,EACd,mBAAmB,EACpB,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;IAElC,MAAM,eAAe,GAAG,sBAAsB,CAAC,cAAc,EAAE,aAAa,CAAC,CAAA;IAE7E,MAAM,GAAG,GAAG,eAAe,CAAC,GAAG,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAA;IAC7C,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,CAAC,EAAE,WAAW,CAAC,CAAA;IAEnD,IAAI,mBAAmB,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;QACtC,MAAM,IAAI,KAAK,CAAC,kCAAkC,mBAAmB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;KAClF;IAED,OAAO;QACL,aAAa;QACb,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;KAChC,CAAA;AACH,CAAC"}

View File

@ -0,0 +1,7 @@
import * as tf from '@tensorflow/tfjs-core';
import { ParamMapping } from '../common';
import { NetParams } from './types';
export declare function extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap): {
params: NetParams;
paramMappings: ParamMapping[];
};

View File

@ -0,0 +1,19 @@
import { disposeUnusedWeightTensors, extractWeightEntryFactory } from '../common';
export function extractParamsFromWeigthMap(weightMap) {
const paramMappings = [];
const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings);
function extractFcParams(prefix) {
const weights = extractWeightEntry(`${prefix}/weights`, 2);
const bias = extractWeightEntry(`${prefix}/bias`, 1);
return { weights, bias };
}
const params = {
fc: {
age: extractFcParams('fc/age'),
gender: extractFcParams('fc/gender')
}
};
disposeUnusedWeightTensors(weightMap, paramMappings);
return { params, paramMappings };
}
//# sourceMappingURL=extractParamsFromWeigthMap.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"extractParamsFromWeigthMap.js","sourceRoot":"","sources":["../../src/ageGenderNet/extractParamsFromWeigthMap.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,0BAA0B,EAAE,yBAAyB,EAA0B,MAAM,WAAW,CAAC;AAG1G,MAAM,UAAU,0BAA0B,CACxC,SAA4B;IAG5B,MAAM,aAAa,GAAmB,EAAE,CAAA;IAExC,MAAM,kBAAkB,GAAG,yBAAyB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAE9E,SAAS,eAAe,CAAC,MAAc;QACrC,MAAM,OAAO,GAAG,kBAAkB,CAAc,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,CAAA;QACvE,MAAM,IAAI,GAAG,kBAAkB,CAAc,GAAG,MAAM,OAAO,EAAE,CAAC,CAAC,CAAA;QACjE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC1B,CAAC;IAED,MAAM,MAAM,GAAG;QACb,EAAE,EAAE;YACF,GAAG,EAAE,eAAe,CAAC,QAAQ,CAAC;YAC9B,MAAM,EAAE,eAAe,CAAC,WAAW,CAAC;SACrC;KACF,CAAA;IAED,0BAA0B,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAEpD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAA;AAClC,CAAC"}

2
build/ageGenderNet/index.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export * from './AgeGenderNet';
export * from './types';

View File

@ -0,0 +1,3 @@
export * from './AgeGenderNet';
export * from './types';
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ageGenderNet/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC"}

21
build/ageGenderNet/types.d.ts vendored Normal file
View File

@ -0,0 +1,21 @@
import * as tf from '@tensorflow/tfjs-core';
import { FCParams } from '../common';
export declare type AgeAndGenderPrediction = {
age: number;
gender: Gender;
genderProbability: number;
};
export declare enum Gender {
FEMALE = "female",
MALE = "male"
}
export declare type NetOutput = {
age: tf.Tensor1D;
gender: tf.Tensor2D;
};
export declare type NetParams = {
fc: {
age: FCParams;
gender: FCParams;
};
};

View File

@ -0,0 +1,6 @@
export var Gender;
(function (Gender) {
Gender["FEMALE"] = "female";
Gender["MALE"] = "male";
})(Gender || (Gender = {}));
//# sourceMappingURL=types.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ageGenderNet/types.ts"],"names":[],"mappings":"AAUA,MAAM,CAAN,IAAY,MAGX;AAHD,WAAY,MAAM;IAChB,2BAAiB,CAAA;IACjB,uBAAa,CAAA;AACf,CAAC,EAHW,MAAM,KAAN,MAAM,QAGjB"}

10
build/classes/BoundingBox.d.ts vendored Normal file
View File

@ -0,0 +1,10 @@
import { Box } from './Box';
export interface IBoundingBox {
left: number;
top: number;
right: number;
bottom: number;
}
export declare class BoundingBox extends Box<BoundingBox> implements IBoundingBox {
constructor(left: number, top: number, right: number, bottom: number, allowNegativeDimensions?: boolean);
}

View File

@ -0,0 +1,7 @@
import { Box } from './Box';
export class BoundingBox extends Box {
constructor(left, top, right, bottom, allowNegativeDimensions = false) {
super({ left, top, right, bottom }, allowNegativeDimensions);
}
}
//# sourceMappingURL=BoundingBox.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"BoundingBox.js","sourceRoot":"","sources":["../../src/classes/BoundingBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAS5B,MAAM,OAAO,WAAY,SAAQ,GAAgB;IAC/C,YAAY,IAAY,EAAE,GAAW,EAAE,KAAa,EAAE,MAAc,EAAE,0BAAmC,KAAK;QAC5G,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAA;IAC9D,CAAC;CACF"}

46
build/classes/Box.d.ts vendored Normal file
View File

@ -0,0 +1,46 @@
import { IBoundingBox } from './BoundingBox';
import { IDimensions } from './Dimensions';
import { Point } from './Point';
import { IRect } from './Rect';
export declare class Box<BoxType = any> implements IBoundingBox, IRect {
static isRect(rect: any): boolean;
static assertIsValidBox(box: any, callee: string, allowNegativeDimensions?: boolean): void;
private _x;
private _y;
private _width;
private _height;
constructor(_box: IBoundingBox | IRect, allowNegativeDimensions?: boolean);
get x(): number;
get y(): number;
get width(): number;
get height(): number;
get left(): number;
get top(): number;
get right(): number;
get bottom(): number;
get area(): number;
get topLeft(): Point;
get topRight(): Point;
get bottomLeft(): Point;
get bottomRight(): Point;
round(): Box<BoxType>;
floor(): Box<BoxType>;
toSquare(): Box<BoxType>;
rescale(s: IDimensions | number): Box<BoxType>;
pad(padX: number, padY: number): Box<BoxType>;
clipAtImageBorders(imgWidth: number, imgHeight: number): Box<BoxType>;
shift(sx: number, sy: number): Box<BoxType>;
padAtBorders(imageHeight: number, imageWidth: number): {
dy: number;
edy: number;
dx: number;
edx: number;
y: number;
ey: number;
x: number;
ex: number;
w: number;
h: number;
};
calibrate(region: Box): Box<any>;
}

140
build/classes/Box.js Normal file
View File

@ -0,0 +1,140 @@
import { isDimensions, isValidNumber } from '../utils';
import { Point } from './Point';
export class Box {
constructor(_box, allowNegativeDimensions = true) {
const box = (_box || {});
const isBbox = [box.left, box.top, box.right, box.bottom].every(isValidNumber);
const isRect = [box.x, box.y, box.width, box.height].every(isValidNumber);
if (!isRect && !isBbox) {
throw new Error(`Box.constructor - expected box to be IBoundingBox | IRect, instead have ${JSON.stringify(box)}`);
}
const [x, y, width, height] = isRect
? [box.x, box.y, box.width, box.height]
: [box.left, box.top, box.right - box.left, box.bottom - box.top];
Box.assertIsValidBox({ x, y, width, height }, 'Box.constructor', allowNegativeDimensions);
this._x = x;
this._y = y;
this._width = width;
this._height = height;
}
static isRect(rect) {
return !!rect && [rect.x, rect.y, rect.width, rect.height].every(isValidNumber);
}
static assertIsValidBox(box, callee, allowNegativeDimensions = false) {
if (!Box.isRect(box)) {
throw new Error(`${callee} - invalid box: ${JSON.stringify(box)}, expected object with properties x, y, width, height`);
}
if (!allowNegativeDimensions && (box.width < 0 || box.height < 0)) {
throw new Error(`${callee} - width (${box.width}) and height (${box.height}) must be positive numbers`);
}
}
get x() { return this._x; }
get y() { return this._y; }
get width() { return this._width; }
get height() { return this._height; }
get left() { return this.x; }
get top() { return this.y; }
get right() { return this.x + this.width; }
get bottom() { return this.y + this.height; }
get area() { return this.width * this.height; }
get topLeft() { return new Point(this.left, this.top); }
get topRight() { return new Point(this.right, this.top); }
get bottomLeft() { return new Point(this.left, this.bottom); }
get bottomRight() { return new Point(this.right, this.bottom); }
round() {
const [x, y, width, height] = [this.x, this.y, this.width, this.height]
.map(val => Math.round(val));
return new Box({ x, y, width, height });
}
floor() {
const [x, y, width, height] = [this.x, this.y, this.width, this.height]
.map(val => Math.floor(val));
return new Box({ x, y, width, height });
}
toSquare() {
let { x, y, width, height } = this;
const diff = Math.abs(width - height);
if (width < height) {
x -= (diff / 2);
width += diff;
}
if (height < width) {
y -= (diff / 2);
height += diff;
}
return new Box({ x, y, width, height });
}
rescale(s) {
const scaleX = isDimensions(s) ? s.width : s;
const scaleY = isDimensions(s) ? s.height : s;
return new Box({
x: this.x * scaleX,
y: this.y * scaleY,
width: this.width * scaleX,
height: this.height * scaleY
});
}
pad(padX, padY) {
let [x, y, width, height] = [
this.x - (padX / 2),
this.y - (padY / 2),
this.width + padX,
this.height + padY
];
return new Box({ x, y, width, height });
}
clipAtImageBorders(imgWidth, imgHeight) {
const { x, y, right, bottom } = this;
const clippedX = Math.max(x, 0);
const clippedY = Math.max(y, 0);
const newWidth = right - clippedX;
const newHeight = bottom - clippedY;
const clippedWidth = Math.min(newWidth, imgWidth - clippedX);
const clippedHeight = Math.min(newHeight, imgHeight - clippedY);
return (new Box({ x: clippedX, y: clippedY, width: clippedWidth, height: clippedHeight })).floor();
}
shift(sx, sy) {
const { width, height } = this;
const x = this.x + sx;
const y = this.y + sy;
return new Box({ x, y, width, height });
}
padAtBorders(imageHeight, imageWidth) {
const w = this.width + 1;
const h = this.height + 1;
let dx = 1;
let dy = 1;
let edx = w;
let edy = h;
let x = this.left;
let y = this.top;
let ex = this.right;
let ey = this.bottom;
if (ex > imageWidth) {
edx = -ex + imageWidth + w;
ex = imageWidth;
}
if (ey > imageHeight) {
edy = -ey + imageHeight + h;
ey = imageHeight;
}
if (x < 1) {
edy = 2 - x;
x = 1;
}
if (y < 1) {
edy = 2 - y;
y = 1;
}
return { dy, edy, dx, edx, y, ey, x, ex, w, h };
}
calibrate(region) {
return new Box({
left: this.left + (region.left * this.width),
top: this.top + (region.top * this.height),
right: this.right + (region.right * this.width),
bottom: this.bottom + (region.bottom * this.height)
}).toSquare().round();
}
}
//# sourceMappingURL=Box.js.map

1
build/classes/Box.js.map Normal file

File diff suppressed because one or more lines are too long

12
build/classes/Dimensions.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
export interface IDimensions {
width: number;
height: number;
}
export declare class Dimensions implements IDimensions {
private _width;
private _height;
constructor(width: number, height: number);
get width(): number;
get height(): number;
reverse(): Dimensions;
}

View File

@ -0,0 +1,16 @@
import { isValidNumber } from '../utils';
export class Dimensions {
constructor(width, height) {
if (!isValidNumber(width) || !isValidNumber(height)) {
throw new Error(`Dimensions.constructor - expected width and height to be valid numbers, instead have ${JSON.stringify({ width, height })}`);
}
this._width = width;
this._height = height;
}
get width() { return this._width; }
get height() { return this._height; }
reverse() {
return new Dimensions(1 / this.width, 1 / this.height);
}
}
//# sourceMappingURL=Dimensions.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"Dimensions.js","sourceRoot":"","sources":["../../src/classes/Dimensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAOzC,MAAM,OAAO,UAAU;IAKrB,YAAY,KAAa,EAAE,MAAc;QACvC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE;YACnD,MAAM,IAAI,KAAK,CAAC,wFAAwF,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAA;SAC7I;QAED,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;IACvB,CAAC;IAED,IAAW,KAAK,KAAa,OAAO,IAAI,CAAC,MAAM,CAAA,CAAC,CAAC;IACjD,IAAW,MAAM,KAAa,OAAO,IAAI,CAAC,OAAO,CAAA,CAAC,CAAC;IAE5C,OAAO;QACZ,OAAO,IAAI,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;IACxD,CAAC;CACF"}

12
build/classes/FaceDetection.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
import { Box } from './Box';
import { IDimensions } from './Dimensions';
import { ObjectDetection } from './ObjectDetection';
import { Rect } from './Rect';
export interface IFaceDetecion {
score: number;
box: Box;
}
export declare class FaceDetection extends ObjectDetection implements IFaceDetecion {
constructor(score: number, relativeBox: Rect, imageDims: IDimensions);
forSize(width: number, height: number): FaceDetection;
}

View File

@ -0,0 +1,11 @@
import { ObjectDetection } from './ObjectDetection';
export class FaceDetection extends ObjectDetection {
constructor(score, relativeBox, imageDims) {
super(score, score, '', relativeBox, imageDims);
}
forSize(width, height) {
const { score, relativeBox, imageDims } = super.forSize(width, height);
return new FaceDetection(score, relativeBox, imageDims);
}
}
//# sourceMappingURL=FaceDetection.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"FaceDetection.js","sourceRoot":"","sources":["../../src/classes/FaceDetection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAQpD,MAAM,OAAO,aAAc,SAAQ,eAAe;IAChD,YACE,KAAa,EACb,WAAiB,EACjB,SAAsB;QAEtB,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,SAAS,CAAC,CAAA;IACjD,CAAC;IAEM,OAAO,CAAC,KAAa,EAAE,MAAc;QAC1C,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACtE,OAAO,IAAI,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,CAAA;IACzD,CAAC;CACF"}

42
build/classes/FaceLandmarks.d.ts vendored Normal file
View File

@ -0,0 +1,42 @@
import { IBoundingBox } from './BoundingBox';
import { Box } from './Box';
import { Dimensions, IDimensions } from './Dimensions';
import { FaceDetection } from './FaceDetection';
import { Point } from './Point';
import { IRect } from './Rect';
export interface IFaceLandmarks {
positions: Point[];
shift: Point;
}
export declare class FaceLandmarks implements IFaceLandmarks {
protected _shift: Point;
protected _positions: Point[];
protected _imgDims: Dimensions;
constructor(relativeFaceLandmarkPositions: Point[], imgDims: IDimensions, shift?: Point);
get shift(): Point;
get imageWidth(): number;
get imageHeight(): number;
get positions(): Point[];
get relativePositions(): Point[];
forSize<T extends FaceLandmarks>(width: number, height: number): T;
shiftBy<T extends FaceLandmarks>(x: number, y: number): T;
shiftByPoint<T extends FaceLandmarks>(pt: Point): T;
/**
* Aligns the face landmarks after face detection from the relative positions of the faces
* bounding box, or it's current shift. This function should be used to align the face images
* after face detection has been performed, before they are passed to the face recognition net.
* This will make the computed face descriptor more accurate.
*
* @param detection (optional) The bounding box of the face or the face detection result. If
* no argument was passed the position of the face landmarks are assumed to be relative to
* it's current shift.
* @returns The bounding box of the aligned face.
*/
align(detection?: FaceDetection | IRect | IBoundingBox | null, options?: {
useDlibAlignment?: boolean;
minBoxPadding?: number;
}): Box;
private alignDlib;
private alignMinBbox;
protected getRefPointsForAlignment(): Point[];
}

View File

@ -0,0 +1,79 @@
import { minBbox } from '../ops';
import { getCenterPoint } from '../utils';
import { Box } from './Box';
import { Dimensions } from './Dimensions';
import { FaceDetection } from './FaceDetection';
import { Point } from './Point';
import { Rect } from './Rect';
// face alignment constants
const relX = 0.5;
const relY = 0.43;
const relScale = 0.45;
export class FaceLandmarks {
constructor(relativeFaceLandmarkPositions, imgDims, shift = new Point(0, 0)) {
const { width, height } = imgDims;
this._imgDims = new Dimensions(width, height);
this._shift = shift;
this._positions = relativeFaceLandmarkPositions.map(pt => pt.mul(new Point(width, height)).add(shift));
}
get shift() { return new Point(this._shift.x, this._shift.y); }
get imageWidth() { return this._imgDims.width; }
get imageHeight() { return this._imgDims.height; }
get positions() { return this._positions; }
get relativePositions() {
return this._positions.map(pt => pt.sub(this._shift).div(new Point(this.imageWidth, this.imageHeight)));
}
forSize(width, height) {
return new this.constructor(this.relativePositions, { width, height });
}
shiftBy(x, y) {
return new this.constructor(this.relativePositions, this._imgDims, new Point(x, y));
}
shiftByPoint(pt) {
return this.shiftBy(pt.x, pt.y);
}
/**
* Aligns the face landmarks after face detection from the relative positions of the faces
* bounding box, or it's current shift. This function should be used to align the face images
* after face detection has been performed, before they are passed to the face recognition net.
* This will make the computed face descriptor more accurate.
*
* @param detection (optional) The bounding box of the face or the face detection result. If
* no argument was passed the position of the face landmarks are assumed to be relative to
* it's current shift.
* @returns The bounding box of the aligned face.
*/
align(detection, options = {}) {
if (detection) {
const box = detection instanceof FaceDetection
? detection.box.floor()
: new Box(detection);
return this.shiftBy(box.x, box.y).align(null, options);
}
const { useDlibAlignment, minBoxPadding } = Object.assign({}, { useDlibAlignment: false, minBoxPadding: 0.2 }, options);
if (useDlibAlignment) {
return this.alignDlib();
}
return this.alignMinBbox(minBoxPadding);
}
alignDlib() {
const centers = this.getRefPointsForAlignment();
const [leftEyeCenter, rightEyeCenter, mouthCenter] = centers;
const distToMouth = (pt) => mouthCenter.sub(pt).magnitude();
const eyeToMouthDist = (distToMouth(leftEyeCenter) + distToMouth(rightEyeCenter)) / 2;
const size = Math.floor(eyeToMouthDist / relScale);
const refPoint = getCenterPoint(centers);
// TODO: pad in case rectangle is out of image bounds
const x = Math.floor(Math.max(0, refPoint.x - (relX * size)));
const y = Math.floor(Math.max(0, refPoint.y - (relY * size)));
return new Rect(x, y, Math.min(size, this.imageWidth + x), Math.min(size, this.imageHeight + y));
}
alignMinBbox(padding) {
const box = minBbox(this.positions);
return box.pad(box.width * padding, box.height * padding);
}
getRefPointsForAlignment() {
throw new Error('getRefPointsForAlignment not implemented by base class');
}
}
//# sourceMappingURL=FaceLandmarks.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"FaceLandmarks.js","sourceRoot":"","sources":["../../src/classes/FaceLandmarks.ts"],"names":[],"mappings":"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"}

5
build/classes/FaceLandmarks5.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
import { FaceLandmarks } from './FaceLandmarks';
import { Point } from './Point';
export declare class FaceLandmarks5 extends FaceLandmarks {
protected getRefPointsForAlignment(): Point[];
}

View File

@ -0,0 +1,13 @@
import { getCenterPoint } from '../utils';
import { FaceLandmarks } from './FaceLandmarks';
export class FaceLandmarks5 extends FaceLandmarks {
getRefPointsForAlignment() {
const pts = this.positions;
return [
pts[0],
pts[1],
getCenterPoint([pts[3], pts[4]])
];
}
}
//# sourceMappingURL=FaceLandmarks5.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"FaceLandmarks5.js","sourceRoot":"","sources":["../../src/classes/FaceLandmarks5.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhD,MAAM,OAAO,cAAe,SAAQ,aAAa;IAErC,wBAAwB;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAA;QAC1B,OAAO;YACL,GAAG,CAAC,CAAC,CAAC;YACN,GAAG,CAAC,CAAC,CAAC;YACN,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;SACjC,CAAA;IACH,CAAC;CACF"}

12
build/classes/FaceLandmarks68.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
import { FaceLandmarks } from './FaceLandmarks';
import { Point } from './Point';
export declare class FaceLandmarks68 extends FaceLandmarks {
getJawOutline(): Point[];
getLeftEyeBrow(): Point[];
getRightEyeBrow(): Point[];
getNose(): Point[];
getLeftEye(): Point[];
getRightEye(): Point[];
getMouth(): Point[];
protected getRefPointsForAlignment(): Point[];
}

View File

@ -0,0 +1,33 @@
import { getCenterPoint } from '../utils';
import { FaceLandmarks } from './FaceLandmarks';
export class FaceLandmarks68 extends FaceLandmarks {
getJawOutline() {
return this.positions.slice(0, 17);
}
getLeftEyeBrow() {
return this.positions.slice(17, 22);
}
getRightEyeBrow() {
return this.positions.slice(22, 27);
}
getNose() {
return this.positions.slice(27, 36);
}
getLeftEye() {
return this.positions.slice(36, 42);
}
getRightEye() {
return this.positions.slice(42, 48);
}
getMouth() {
return this.positions.slice(48, 68);
}
getRefPointsForAlignment() {
return [
this.getLeftEye(),
this.getRightEye(),
this.getMouth()
].map(getCenterPoint);
}
}
//# sourceMappingURL=FaceLandmarks68.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"FaceLandmarks68.js","sourceRoot":"","sources":["../../src/classes/FaceLandmarks68.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,MAAM,OAAO,eAAgB,SAAQ,aAAa;IACzC,aAAa;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACpC,CAAC;IAEM,cAAc;QACnB,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACrC,CAAC;IAEM,eAAe;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACrC,CAAC;IAEM,OAAO;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACrC,CAAC;IAEM,UAAU;QACf,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACrC,CAAC;IAEM,WAAW;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACrC,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACrC,CAAC;IAES,wBAAwB;QAChC,OAAO;YACL,IAAI,CAAC,UAAU,EAAE;YACjB,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,CAAC,QAAQ,EAAE;SAChB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IACvB,CAAC;CACF"}

12
build/classes/FaceMatch.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
export interface IFaceMatch {
label: string;
distance: number;
}
export declare class FaceMatch implements IFaceMatch {
private _label;
private _distance;
constructor(label: string, distance: number);
get label(): string;
get distance(): number;
toString(withDistance?: boolean): string;
}

View File

@ -0,0 +1,13 @@
import { round } from '../utils';
export class FaceMatch {
constructor(label, distance) {
this._label = label;
this._distance = distance;
}
get label() { return this._label; }
get distance() { return this._distance; }
toString(withDistance = true) {
return `${this.label}${withDistance ? ` (${round(this.distance)})` : ''}`;
}
}
//# sourceMappingURL=FaceMatch.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"FaceMatch.js","sourceRoot":"","sources":["../../src/classes/FaceMatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAOjC,MAAM,OAAO,SAAS;IAIpB,YAAY,KAAa,EAAE,QAAgB;QACzC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAA;IAC3B,CAAC;IAED,IAAW,KAAK,KAAa,OAAO,IAAI,CAAC,MAAM,CAAA,CAAC,CAAC;IACjD,IAAW,QAAQ,KAAa,OAAO,IAAI,CAAC,SAAS,CAAA,CAAC,CAAC;IAEhD,QAAQ,CAAC,eAAwB,IAAI;QAC1C,OAAO,GAAG,IAAI,CAAC,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;IAC3E,CAAC;CACF"}

9
build/classes/LabeledBox.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
import { IBoundingBox } from './BoundingBox';
import { Box } from './Box';
import { IRect } from './Rect';
export declare class LabeledBox extends Box<LabeledBox> {
static assertIsValidLabeledBox(box: any, callee: string): void;
private _label;
constructor(box: IBoundingBox | IRect | any, label: number);
get label(): number;
}

View File

@ -0,0 +1,16 @@
import { isValidNumber } from '../utils';
import { Box } from './Box';
export class LabeledBox extends Box {
constructor(box, label) {
super(box);
this._label = label;
}
static assertIsValidLabeledBox(box, callee) {
Box.assertIsValidBox(box, callee);
if (!isValidNumber(box.label)) {
throw new Error(`${callee} - expected property label (${box.label}) to be a number`);
}
}
get label() { return this._label; }
}
//# sourceMappingURL=LabeledBox.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"LabeledBox.js","sourceRoot":"","sources":["../../src/classes/LabeledBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAG5B,MAAM,OAAO,UAAW,SAAQ,GAAe;IAY7C,YAAY,GAA+B,EAAE,KAAa;QACxD,KAAK,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;IACrB,CAAC;IAbM,MAAM,CAAC,uBAAuB,CAAC,GAAQ,EAAE,MAAc;QAC5D,GAAG,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAEjC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YAC7B,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,+BAA+B,GAAG,CAAC,KAAK,kBAAkB,CAAC,CAAA;SACrF;IACH,CAAC;IASD,IAAW,KAAK,KAAa,OAAO,IAAI,CAAC,MAAM,CAAA,CAAC,CAAC;CAElD"}

View File

@ -0,0 +1,9 @@
export declare class LabeledFaceDescriptors {
private _label;
private _descriptors;
constructor(label: string, descriptors: Float32Array[]);
get label(): string;
get descriptors(): Float32Array[];
toJSON(): any;
static fromJSON(json: any): LabeledFaceDescriptors;
}

View File

@ -0,0 +1,27 @@
export class LabeledFaceDescriptors {
constructor(label, descriptors) {
if (!(typeof label === 'string')) {
throw new Error('LabeledFaceDescriptors - constructor expected label to be a string');
}
if (!Array.isArray(descriptors) || descriptors.some(desc => !(desc instanceof Float32Array))) {
throw new Error('LabeledFaceDescriptors - constructor expected descriptors to be an array of Float32Array');
}
this._label = label;
this._descriptors = descriptors;
}
get label() { return this._label; }
get descriptors() { return this._descriptors; }
toJSON() {
return {
label: this.label,
descriptors: this.descriptors.map((d) => Array.from(d))
};
}
static fromJSON(json) {
const descriptors = json.descriptors.map((d) => {
return new Float32Array(d);
});
return new LabeledFaceDescriptors(json.label, descriptors);
}
}
//# sourceMappingURL=LabeledFaceDescriptors.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"LabeledFaceDescriptors.js","sourceRoot":"","sources":["../../src/classes/LabeledFaceDescriptors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,sBAAsB;IAIjC,YAAY,KAAa,EAAE,WAA2B;QACpD,IAAI,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,EAAE;YAChC,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAA;SACtF;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,YAAY,YAAY,CAAC,CAAC,EAAE;YAC5F,MAAM,IAAI,KAAK,CAAC,0FAA0F,CAAC,CAAA;SAC5G;QAED,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,YAAY,GAAG,WAAW,CAAA;IACjC,CAAC;IAED,IAAW,KAAK,KAAa,OAAO,IAAI,CAAC,MAAM,CAAA,CAAC,CAAC;IACjD,IAAW,WAAW,KAAqB,OAAO,IAAI,CAAC,YAAY,CAAA,CAAC,CAAC;IAE9D,MAAM;QACX,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACxD,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,QAAQ,CAAC,IAAS;QAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE;YAClD,OAAO,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,sBAAsB,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC7D,CAAC;CAEF"}

20
build/classes/ObjectDetection.d.ts vendored Normal file
View File

@ -0,0 +1,20 @@
import { Box } from './Box';
import { Dimensions, IDimensions } from './Dimensions';
import { IRect } from './Rect';
export declare class ObjectDetection {
private _score;
private _classScore;
private _className;
private _box;
private _imageDims;
constructor(score: number, classScore: number, className: string, relativeBox: IRect, imageDims: IDimensions);
get score(): number;
get classScore(): number;
get className(): string;
get box(): Box;
get imageDims(): Dimensions;
get imageWidth(): number;
get imageHeight(): number;
get relativeBox(): Box;
forSize(width: number, height: number): ObjectDetection;
}

View File

@ -0,0 +1,23 @@
import { Box } from './Box';
import { Dimensions } from './Dimensions';
export class ObjectDetection {
constructor(score, classScore, className, relativeBox, imageDims) {
this._imageDims = new Dimensions(imageDims.width, imageDims.height);
this._score = score;
this._classScore = classScore;
this._className = className;
this._box = new Box(relativeBox).rescale(this._imageDims);
}
get score() { return this._score; }
get classScore() { return this._classScore; }
get className() { return this._className; }
get box() { return this._box; }
get imageDims() { return this._imageDims; }
get imageWidth() { return this.imageDims.width; }
get imageHeight() { return this.imageDims.height; }
get relativeBox() { return new Box(this._box).rescale(this.imageDims.reverse()); }
forSize(width, height) {
return new ObjectDetection(this.score, this.classScore, this.className, this.relativeBox, { width, height });
}
}
//# sourceMappingURL=ObjectDetection.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"ObjectDetection.js","sourceRoot":"","sources":["../../src/classes/ObjectDetection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAe,MAAM,cAAc,CAAC;AAGvD,MAAM,OAAO,eAAe;IAO1B,YACE,KAAa,EACb,UAAkB,EAClB,SAAiB,EACjB,WAAkB,EAClB,SAAsB;QAEtB,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;QACnE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,WAAW,GAAG,UAAU,CAAA;QAC7B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC3D,CAAC;IAED,IAAW,KAAK,KAAa,OAAO,IAAI,CAAC,MAAM,CAAA,CAAC,CAAC;IACjD,IAAW,UAAU,KAAa,OAAO,IAAI,CAAC,WAAW,CAAA,CAAC,CAAC;IAC3D,IAAW,SAAS,KAAa,OAAO,IAAI,CAAC,UAAU,CAAA,CAAC,CAAC;IACzD,IAAW,GAAG,KAAU,OAAO,IAAI,CAAC,IAAI,CAAA,CAAC,CAAC;IAC1C,IAAW,SAAS,KAAiB,OAAO,IAAI,CAAC,UAAU,CAAA,CAAC,CAAC;IAC7D,IAAW,UAAU,KAAa,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA,CAAC,CAAC;IAC/D,IAAW,WAAW,KAAa,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAA,CAAC,CAAC;IACjE,IAAW,WAAW,KAAU,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA,CAAC,CAAC;IAEtF,OAAO,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,eAAe,CACxB,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,WAAW,EAChB,EAAE,KAAK,EAAE,MAAM,EAAC,CACjB,CAAA;IACH,CAAC;CACF"}

18
build/classes/Point.d.ts vendored Normal file
View File

@ -0,0 +1,18 @@
export interface IPoint {
x: number;
y: number;
}
export declare class Point implements IPoint {
private _x;
private _y;
constructor(x: number, y: number);
get x(): number;
get y(): number;
add(pt: IPoint): Point;
sub(pt: IPoint): Point;
mul(pt: IPoint): Point;
div(pt: IPoint): Point;
abs(): Point;
magnitude(): number;
floor(): Point;
}

30
build/classes/Point.js Normal file
View File

@ -0,0 +1,30 @@
export class Point {
constructor(x, y) {
this._x = x;
this._y = y;
}
get x() { return this._x; }
get y() { return this._y; }
add(pt) {
return new Point(this.x + pt.x, this.y + pt.y);
}
sub(pt) {
return new Point(this.x - pt.x, this.y - pt.y);
}
mul(pt) {
return new Point(this.x * pt.x, this.y * pt.y);
}
div(pt) {
return new Point(this.x / pt.x, this.y / pt.y);
}
abs() {
return new Point(Math.abs(this.x), Math.abs(this.y));
}
magnitude() {
return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
}
floor() {
return new Point(Math.floor(this.x), Math.floor(this.y));
}
}
//# sourceMappingURL=Point.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"Point.js","sourceRoot":"","sources":["../../src/classes/Point.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,KAAK;IAIhB,YAAY,CAAS,EAAE,CAAS;QAC9B,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;QACX,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;IACb,CAAC;IAED,IAAI,CAAC,KAAa,OAAO,IAAI,CAAC,EAAE,CAAA,CAAC,CAAC;IAClC,IAAI,CAAC,KAAa,OAAO,IAAI,CAAC,EAAE,CAAA,CAAC,CAAC;IAE3B,GAAG,CAAC,EAAU;QACnB,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;IAChD,CAAC;IAEM,GAAG,CAAC,EAAU;QACnB,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;IAChD,CAAC;IAEM,GAAG,CAAC,EAAU;QACnB,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;IAChD,CAAC;IAEM,GAAG,CAAC,EAAU;QACnB,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;IAChD,CAAC;IAEM,GAAG;QACR,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACtD,CAAC;IAEM,SAAS;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC7D,CAAC;IAEM,KAAK;QACV,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1D,CAAC;CACF"}

11
build/classes/PredictedBox.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
import { IBoundingBox } from './BoundingBox';
import { LabeledBox } from './LabeledBox';
import { IRect } from './Rect';
export declare class PredictedBox extends LabeledBox {
static assertIsValidPredictedBox(box: any, callee: string): void;
private _score;
private _classScore;
constructor(box: IBoundingBox | IRect | any, label: number, score: number, classScore: number);
get score(): number;
get classScore(): number;
}

View File

@ -0,0 +1,19 @@
import { isValidProbablitiy } from '../utils';
import { LabeledBox } from './LabeledBox';
export class PredictedBox extends LabeledBox {
constructor(box, label, score, classScore) {
super(box, label);
this._score = score;
this._classScore = classScore;
}
static assertIsValidPredictedBox(box, callee) {
LabeledBox.assertIsValidLabeledBox(box, callee);
if (!isValidProbablitiy(box.score)
|| !isValidProbablitiy(box.classScore)) {
throw new Error(`${callee} - expected properties score (${box.score}) and (${box.classScore}) to be a number between [0, 1]`);
}
}
get score() { return this._score; }
get classScore() { return this._classScore; }
}
//# sourceMappingURL=PredictedBox.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"PredictedBox.js","sourceRoot":"","sources":["../../src/classes/PredictedBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,MAAM,OAAO,YAAa,SAAQ,UAAU;IAgB1C,YAAY,GAA+B,EAAE,KAAa,EAAE,KAAa,EAAE,UAAkB;QAC3F,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACjB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,WAAW,GAAG,UAAU,CAAA;IAC/B,CAAC;IAlBM,MAAM,CAAC,yBAAyB,CAAC,GAAQ,EAAE,MAAc;QAC9D,UAAU,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAE/C,IACE,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC;eAC3B,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,EACtC;YACA,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,iCAAiC,GAAG,CAAC,KAAK,UAAU,GAAG,CAAC,UAAU,iCAAiC,CAAC,CAAA;SAC9H;IACH,CAAC;IAWD,IAAW,KAAK,KAAa,OAAO,IAAI,CAAC,MAAM,CAAA,CAAC,CAAC;IACjD,IAAW,UAAU,KAAa,OAAO,IAAI,CAAC,WAAW,CAAA,CAAC,CAAC;CAE5D"}

10
build/classes/Rect.d.ts vendored Normal file
View File

@ -0,0 +1,10 @@
import { Box } from './Box';
export interface IRect {
x: number;
y: number;
width: number;
height: number;
}
export declare class Rect extends Box<Rect> implements IRect {
constructor(x: number, y: number, width: number, height: number, allowNegativeDimensions?: boolean);
}

7
build/classes/Rect.js Normal file
View File

@ -0,0 +1,7 @@
import { Box } from './Box';
export class Rect extends Box {
constructor(x, y, width, height, allowNegativeDimensions = false) {
super({ x, y, width, height }, allowNegativeDimensions);
}
}
//# sourceMappingURL=Rect.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"Rect.js","sourceRoot":"","sources":["../../src/classes/Rect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAS5B,MAAM,OAAO,IAAK,SAAQ,GAAS;IACjC,YAAY,CAAS,EAAE,CAAS,EAAE,KAAa,EAAE,MAAc,EAAE,0BAAmC,KAAK;QACvG,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAA;IACzD,CAAC;CACF"}

14
build/classes/index.d.ts vendored Normal file
View File

@ -0,0 +1,14 @@
export * from './BoundingBox';
export * from './Box';
export * from './Dimensions';
export * from './FaceDetection';
export * from './FaceLandmarks';
export * from './FaceLandmarks5';
export * from './FaceLandmarks68';
export * from './FaceMatch';
export * from './LabeledBox';
export * from './LabeledFaceDescriptors';
export * from './ObjectDetection';
export * from './Point';
export * from './PredictedBox';
export * from './Rect';

15
build/classes/index.js Normal file
View File

@ -0,0 +1,15 @@
export * from './BoundingBox';
export * from './Box';
export * from './Dimensions';
export * from './FaceDetection';
export * from './FaceLandmarks';
export * from './FaceLandmarks5';
export * from './FaceLandmarks68';
export * from './FaceMatch';
export * from './LabeledBox';
export * from './LabeledFaceDescriptors';
export * from './ObjectDetection';
export * from './Point';
export * from './PredictedBox';
export * from './Rect';
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/classes/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,OAAO,CAAA;AACrB,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAA;AACjC,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,QAAQ,CAAA"}

3
build/common/convLayer.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
import * as tf from '@tensorflow/tfjs-core';
import { ConvParams } from './types';
export declare function convLayer(x: tf.Tensor4D, params: ConvParams, padding?: 'valid' | 'same', withRelu?: boolean): tf.Tensor4D;

View File

@ -0,0 +1,8 @@
import * as tf from '@tensorflow/tfjs-core';
export function convLayer(x, params, padding = 'same', withRelu = false) {
return tf.tidy(() => {
const out = tf.add(tf.conv2d(x, params.filters, [1, 1], padding), params.bias);
return withRelu ? tf.relu(out) : out;
});
}
//# sourceMappingURL=convLayer.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"convLayer.js","sourceRoot":"","sources":["../../src/common/convLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAI5C,MAAM,UAAU,SAAS,CACvB,CAAc,EACd,MAAkB,EAClB,UAA4B,MAAM,EAClC,WAAoB,KAAK;IAEzB,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QAClB,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAChB,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,EAC7C,MAAM,CAAC,IAAI,CACG,CAAA;QAEhB,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;IACtC,CAAC,CAAC,CAAA;AACJ,CAAC"}

View File

@ -0,0 +1,3 @@
import * as tf from '@tensorflow/tfjs-core';
import { SeparableConvParams } from './types';
export declare function depthwiseSeparableConv(x: tf.Tensor4D, params: SeparableConvParams, stride: [number, number]): tf.Tensor4D;

View File

@ -0,0 +1,9 @@
import * as tf from '@tensorflow/tfjs-core';
export function depthwiseSeparableConv(x, params, stride) {
return tf.tidy(() => {
let out = tf.separableConv2d(x, params.depthwise_filter, params.pointwise_filter, stride, 'same');
out = tf.add(out, params.bias);
return out;
});
}
//# sourceMappingURL=depthwiseSeparableConv.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"depthwiseSeparableConv.js","sourceRoot":"","sources":["../../src/common/depthwiseSeparableConv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAI5C,MAAM,UAAU,sBAAsB,CACpC,CAAc,EACd,MAA2B,EAC3B,MAAwB;IAExB,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QAClB,IAAI,GAAG,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;QACjG,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QAC9B,OAAO,GAAG,CAAA;IACZ,CAAC,CAAC,CAAA;AACJ,CAAC"}

View File

@ -0,0 +1,2 @@
import { ParamMapping } from './types';
export declare function disposeUnusedWeightTensors(weightMap: any, paramMappings: ParamMapping[]): void;

View File

@ -0,0 +1,8 @@
export function disposeUnusedWeightTensors(weightMap, paramMappings) {
Object.keys(weightMap).forEach(path => {
if (!paramMappings.some(pm => pm.originalPath === path)) {
weightMap[path].dispose();
}
});
}
//# sourceMappingURL=disposeUnusedWeightTensors.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"disposeUnusedWeightTensors.js","sourceRoot":"","sources":["../../src/common/disposeUnusedWeightTensors.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,0BAA0B,CAAC,SAAc,EAAE,aAA6B;IACtF,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACpC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,KAAK,IAAI,CAAC,EAAE;YACvD,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAA;SAC1B;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}

View File

@ -0,0 +1,2 @@
import { ConvParams, ExtractWeightsFunction, ParamMapping } from './types';
export declare function extractConvParamsFactory(extractWeights: ExtractWeightsFunction, paramMappings: ParamMapping[]): (channelsIn: number, channelsOut: number, filterSize: number, mappedPrefix: string) => ConvParams;

View File

@ -0,0 +1,10 @@
import * as tf from '@tensorflow/tfjs-core';
export function extractConvParamsFactory(extractWeights, paramMappings) {
return function (channelsIn, channelsOut, filterSize, mappedPrefix) {
const filters = tf.tensor4d(extractWeights(channelsIn * channelsOut * filterSize * filterSize), [filterSize, filterSize, channelsIn, channelsOut]);
const bias = tf.tensor1d(extractWeights(channelsOut));
paramMappings.push({ paramPath: `${mappedPrefix}/filters` }, { paramPath: `${mappedPrefix}/bias` });
return { filters, bias };
};
}
//# sourceMappingURL=extractConvParamsFactory.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"extractConvParamsFactory.js","sourceRoot":"","sources":["../../src/common/extractConvParamsFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAI5C,MAAM,UAAU,wBAAwB,CACtC,cAAsC,EACtC,aAA6B;IAG7B,OAAO,UACL,UAAkB,EAClB,WAAmB,EACnB,UAAkB,EAClB,YAAoB;QAGpB,MAAM,OAAO,GAAG,EAAE,CAAC,QAAQ,CACzB,cAAc,CAAC,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,CAAC,EAClE,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,CAAC,CAClD,CAAA;QACD,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QAErD,aAAa,CAAC,IAAI,CAChB,EAAE,SAAS,EAAE,GAAG,YAAY,UAAU,EAAE,EACxC,EAAE,SAAS,EAAE,GAAG,YAAY,OAAO,EAAE,CACtC,CAAA;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC1B,CAAC,CAAA;AAEH,CAAC"}

View File

@ -0,0 +1,2 @@
import { ExtractWeightsFunction, FCParams, ParamMapping } from './types';
export declare function extractFCParamsFactory(extractWeights: ExtractWeightsFunction, paramMappings: ParamMapping[]): (channelsIn: number, channelsOut: number, mappedPrefix: string) => FCParams;

View File

@ -0,0 +1,13 @@
import * as tf from '@tensorflow/tfjs-core';
export function extractFCParamsFactory(extractWeights, paramMappings) {
return function (channelsIn, channelsOut, mappedPrefix) {
const fc_weights = tf.tensor2d(extractWeights(channelsIn * channelsOut), [channelsIn, channelsOut]);
const fc_bias = tf.tensor1d(extractWeights(channelsOut));
paramMappings.push({ paramPath: `${mappedPrefix}/weights` }, { paramPath: `${mappedPrefix}/bias` });
return {
weights: fc_weights,
bias: fc_bias
};
};
}
//# sourceMappingURL=extractFCParamsFactory.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"extractFCParamsFactory.js","sourceRoot":"","sources":["../../src/common/extractFCParamsFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAK5C,MAAM,UAAU,sBAAsB,CACpC,cAAsC,EACtC,aAA6B;IAG7B,OAAO,UACL,UAAkB,EAClB,WAAmB,EACnB,YAAoB;QAGpB,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,UAAU,GAAG,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAA;QACnG,MAAM,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QAExD,aAAa,CAAC,IAAI,CAChB,EAAE,SAAS,EAAE,GAAG,YAAY,UAAU,EAAE,EACxC,EAAE,SAAS,EAAE,GAAG,YAAY,OAAO,EAAE,CACtC,CAAA;QAED,OAAO;YACL,OAAO,EAAE,UAAU;YACnB,IAAI,EAAE,OAAO;SACd,CAAA;IACH,CAAC,CAAA;AAEH,CAAC"}

View File

@ -0,0 +1,3 @@
import { ExtractWeightsFunction, ParamMapping, SeparableConvParams } from './types';
export declare function extractSeparableConvParamsFactory(extractWeights: ExtractWeightsFunction, paramMappings: ParamMapping[]): (channelsIn: number, channelsOut: number, mappedPrefix: string) => SeparableConvParams;
export declare function loadSeparableConvParamsFactory(extractWeightEntry: <T>(originalPath: string, paramRank: number) => T): (prefix: string) => SeparableConvParams;

View File

@ -0,0 +1,20 @@
import * as tf from '@tensorflow/tfjs-core';
import { SeparableConvParams } from './types';
export function extractSeparableConvParamsFactory(extractWeights, paramMappings) {
return function (channelsIn, channelsOut, mappedPrefix) {
const depthwise_filter = tf.tensor4d(extractWeights(3 * 3 * channelsIn), [3, 3, channelsIn, 1]);
const pointwise_filter = tf.tensor4d(extractWeights(channelsIn * channelsOut), [1, 1, channelsIn, channelsOut]);
const bias = tf.tensor1d(extractWeights(channelsOut));
paramMappings.push({ paramPath: `${mappedPrefix}/depthwise_filter` }, { paramPath: `${mappedPrefix}/pointwise_filter` }, { paramPath: `${mappedPrefix}/bias` });
return new SeparableConvParams(depthwise_filter, pointwise_filter, bias);
};
}
export function loadSeparableConvParamsFactory(extractWeightEntry) {
return function (prefix) {
const depthwise_filter = extractWeightEntry(`${prefix}/depthwise_filter`, 4);
const pointwise_filter = extractWeightEntry(`${prefix}/pointwise_filter`, 4);
const bias = extractWeightEntry(`${prefix}/bias`, 1);
return new SeparableConvParams(depthwise_filter, pointwise_filter, bias);
};
}
//# sourceMappingURL=extractSeparableConvParamsFactory.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"extractSeparableConvParamsFactory.js","sourceRoot":"","sources":["../../src/common/extractSeparableConvParamsFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAwC,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEpF,MAAM,UAAU,iCAAiC,CAC/C,cAAsC,EACtC,aAA6B;IAG7B,OAAO,UAAS,UAAkB,EAAE,WAAmB,EAAE,YAAoB;QAC3E,MAAM,gBAAgB,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAAA;QAC/F,MAAM,gBAAgB,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,UAAU,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAA;QAC/G,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QAErD,aAAa,CAAC,IAAI,CAChB,EAAE,SAAS,EAAE,GAAG,YAAY,mBAAmB,EAAE,EACjD,EAAE,SAAS,EAAE,GAAG,YAAY,mBAAmB,EAAE,EACjD,EAAE,SAAS,EAAE,GAAG,YAAY,OAAO,EAAE,CACtC,CAAA;QAED,OAAO,IAAI,mBAAmB,CAC5B,gBAAgB,EAChB,gBAAgB,EAChB,IAAI,CACL,CAAA;IACH,CAAC,CAAA;AAEH,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,kBAAqE;IAGrE,OAAO,UAAU,MAAc;QAC7B,MAAM,gBAAgB,GAAG,kBAAkB,CAAc,GAAG,MAAM,mBAAmB,EAAE,CAAC,CAAC,CAAA;QACzF,MAAM,gBAAgB,GAAG,kBAAkB,CAAc,GAAG,MAAM,mBAAmB,EAAE,CAAC,CAAC,CAAA;QACzF,MAAM,IAAI,GAAG,kBAAkB,CAAc,GAAG,MAAM,OAAO,EAAE,CAAC,CAAC,CAAA;QAEjE,OAAO,IAAI,mBAAmB,CAC5B,gBAAgB,EAChB,gBAAgB,EAChB,IAAI,CACL,CAAA;IACH,CAAC,CAAA;AAEH,CAAC"}

View File

@ -0,0 +1,2 @@
import { ParamMapping } from './types';
export declare function extractWeightEntryFactory(weightMap: any, paramMappings: ParamMapping[]): <T>(originalPath: string, paramRank: number, mappedPath?: string | undefined) => T;

View File

@ -0,0 +1,12 @@
import { isTensor } from '../utils';
export function extractWeightEntryFactory(weightMap, paramMappings) {
return function (originalPath, paramRank, mappedPath) {
const tensor = weightMap[originalPath];
if (!isTensor(tensor, paramRank)) {
throw new Error(`expected weightMap[${originalPath}] to be a Tensor${paramRank}D, instead have ${tensor}`);
}
paramMappings.push({ originalPath, paramPath: mappedPath || originalPath });
return tensor;
};
}
//# sourceMappingURL=extractWeightEntryFactory.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"extractWeightEntryFactory.js","sourceRoot":"","sources":["../../src/common/extractWeightEntryFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,MAAM,UAAU,yBAAyB,CAAC,SAAc,EAAE,aAA6B;IAErF,OAAO,UAAa,YAAoB,EAAE,SAAiB,EAAE,UAAmB;QAC9E,MAAM,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CAAA;QAEtC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE;YAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,YAAY,mBAAmB,SAAS,mBAAmB,MAAM,EAAE,CAAC,CAAA;SAC3G;QAED,aAAa,CAAC,IAAI,CAChB,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,IAAI,YAAY,EAAE,CACxD,CAAA;QAED,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;AAEH,CAAC"}

View File

@ -0,0 +1,4 @@
export declare function extractWeightsFactory(weights: Float32Array): {
extractWeights: (numWeights: number) => Float32Array;
getRemainingWeights: () => Float32Array;
};

View File

@ -0,0 +1,16 @@
export function extractWeightsFactory(weights) {
let remainingWeights = weights;
function extractWeights(numWeights) {
const ret = remainingWeights.slice(0, numWeights);
remainingWeights = remainingWeights.slice(numWeights);
return ret;
}
function getRemainingWeights() {
return remainingWeights;
}
return {
extractWeights,
getRemainingWeights
};
}
//# sourceMappingURL=extractWeightsFactory.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"extractWeightsFactory.js","sourceRoot":"","sources":["../../src/common/extractWeightsFactory.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,qBAAqB,CAAC,OAAqB;IACzD,IAAI,gBAAgB,GAAG,OAAO,CAAA;IAE9B,SAAS,cAAc,CAAC,UAAkB;QACxC,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;QACjD,gBAAgB,GAAG,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QACrD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,SAAS,mBAAmB;QAC1B,OAAO,gBAAgB,CAAA;IACzB,CAAC;IAED,OAAO;QACL,cAAc;QACd,mBAAmB;KACpB,CAAA;AACH,CAAC"}

3
build/common/fullyConnectedLayer.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
import * as tf from '@tensorflow/tfjs-core';
import { FCParams } from './types';
export declare function fullyConnectedLayer(x: tf.Tensor2D, params: FCParams): tf.Tensor2D;

View File

@ -0,0 +1,5 @@
import * as tf from '@tensorflow/tfjs-core';
export function fullyConnectedLayer(x, params) {
return tf.tidy(() => tf.add(tf.matMul(x, params.weights), params.bias));
}
//# sourceMappingURL=fullyConnectedLayer.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"fullyConnectedLayer.js","sourceRoot":"","sources":["../../src/common/fullyConnectedLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAI5C,MAAM,UAAU,mBAAmB,CACjC,CAAc,EACd,MAAgB;IAEhB,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAClB,EAAE,CAAC,GAAG,CACJ,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,EAC5B,MAAM,CAAC,IAAI,CACZ,CACF,CAAA;AACH,CAAC"}

4
build/common/getModelUris.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
export declare function getModelUris(uri: string | undefined, defaultModelName: string): {
modelBaseUri: string;
manifestUri: string;
};

View File

@ -0,0 +1,28 @@
export function getModelUris(uri, defaultModelName) {
const defaultManifestFilename = `${defaultModelName}-weights_manifest.json`;
if (!uri) {
return {
modelBaseUri: '',
manifestUri: defaultManifestFilename
};
}
if (uri === '/') {
return {
modelBaseUri: '/',
manifestUri: `/${defaultManifestFilename}`
};
}
const protocol = uri.startsWith('http://') ? 'http://' : uri.startsWith('https://') ? 'https://' : '';
uri = uri.replace(protocol, '');
const parts = uri.split('/').filter(s => s);
const manifestFile = uri.endsWith('.json')
? parts[parts.length - 1]
: defaultManifestFilename;
let modelBaseUri = protocol + (uri.endsWith('.json') ? parts.slice(0, parts.length - 1) : parts).join('/');
modelBaseUri = uri.startsWith('/') ? `/${modelBaseUri}` : modelBaseUri;
return {
modelBaseUri,
manifestUri: modelBaseUri === '/' ? `/${manifestFile}` : `${modelBaseUri}/${manifestFile}`
};
}
//# sourceMappingURL=getModelUris.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"getModelUris.js","sourceRoot":"","sources":["../../src/common/getModelUris.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,GAAuB,EAAE,gBAAwB;IAC5E,MAAM,uBAAuB,GAAG,GAAG,gBAAgB,wBAAwB,CAAA;IAE3E,IAAI,CAAC,GAAG,EAAE;QACR,OAAO;YACL,YAAY,EAAE,EAAE;YAChB,WAAW,EAAE,uBAAuB;SACrC,CAAA;KACF;IAED,IAAI,GAAG,KAAK,GAAG,EAAE;QACf,OAAO;YACL,YAAY,EAAE,GAAG;YACjB,WAAW,EAAE,IAAI,uBAAuB,EAAE;SAC3C,CAAA;KACF;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACtG,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAEhC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAE3C,MAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;QACxC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACzB,CAAC,CAAC,uBAAuB,CAAA;IAE3B,IAAI,YAAY,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC1G,YAAY,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,EAAE,CAAC,CAAC,CAAC,YAAY,CAAA;IAEtE,OAAO;QACL,YAAY;QACZ,WAAW,EAAE,YAAY,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,YAAY,EAAE,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,YAAY,EAAE;KAC3F,CAAA;AACH,CAAC"}

10
build/common/index.d.ts vendored Normal file
View File

@ -0,0 +1,10 @@
export * from './convLayer';
export * from './depthwiseSeparableConv';
export * from './disposeUnusedWeightTensors';
export * from './extractConvParamsFactory';
export * from './extractFCParamsFactory';
export * from './extractSeparableConvParamsFactory';
export * from './extractWeightEntryFactory';
export * from './extractWeightsFactory';
export * from './getModelUris';
export * from './types';

11
build/common/index.js Normal file
View File

@ -0,0 +1,11 @@
export * from './convLayer';
export * from './depthwiseSeparableConv';
export * from './disposeUnusedWeightTensors';
export * from './extractConvParamsFactory';
export * from './extractFCParamsFactory';
export * from './extractSeparableConvParamsFactory';
export * from './extractWeightEntryFactory';
export * from './extractWeightsFactory';
export * from './getModelUris';
export * from './types';
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,0BAA0B,CAAA;AACxC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA;AACxC,cAAc,qCAAqC,CAAA;AACnD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA;AACvC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA"}

View File

@ -0,0 +1,2 @@
import { ConvParams } from './types';
export declare function loadConvParamsFactory(extractWeightEntry: <T>(originalPath: string, paramRank: number) => T): (prefix: string) => ConvParams;

View File

@ -0,0 +1,8 @@
export function loadConvParamsFactory(extractWeightEntry) {
return function (prefix) {
const filters = extractWeightEntry(`${prefix}/filters`, 4);
const bias = extractWeightEntry(`${prefix}/bias`, 1);
return { filters, bias };
};
}
//# sourceMappingURL=loadConvParamsFactory.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"loadConvParamsFactory.js","sourceRoot":"","sources":["../../src/common/loadConvParamsFactory.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,qBAAqB,CAAC,kBAAqE;IACzG,OAAO,UAAS,MAAc;QAC5B,MAAM,OAAO,GAAG,kBAAkB,CAAc,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,CAAA;QACvE,MAAM,IAAI,GAAG,kBAAkB,CAAc,GAAG,MAAM,OAAO,EAAE,CAAC,CAAC,CAAA;QAEjE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC1B,CAAC,CAAA;AACH,CAAC"}

Some files were not shown because too many files have changed in this diff Show More