added pre-compiled build
parent
c03673f635
commit
b1794ece54
|
@ -1,2 +1 @@
|
|||
node_modules
|
||||
build
|
||||
|
|
|
@ -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[];
|
||||
};
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"NeuralNetwork.js","sourceRoot":"","sources":["../src/NeuralNetwork.ts"],"names":[],"mappings":"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"}
|
|
@ -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[];
|
||||
};
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"AgeGenderNet.js","sourceRoot":"","sources":["../../src/ageGenderNet/AgeGenderNet.ts"],"names":[],"mappings":"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"}
|
|
@ -0,0 +1,6 @@
|
|||
import { ParamMapping } from '../common';
|
||||
import { NetParams } from './types';
|
||||
export declare function extractParams(weights: Float32Array): {
|
||||
params: NetParams;
|
||||
paramMappings: ParamMapping[];
|
||||
};
|
|
@ -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
|
|
@ -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"}
|
|
@ -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[];
|
||||
};
|
|
@ -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
|
|
@ -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"}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './AgeGenderNet';
|
||||
export * from './types';
|
|
@ -0,0 +1,3 @@
|
|||
export * from './AgeGenderNet';
|
||||
export * from './types';
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -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"}
|
|
@ -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;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,6 @@
|
|||
export var Gender;
|
||||
(function (Gender) {
|
||||
Gender["FEMALE"] = "female";
|
||||
Gender["MALE"] = "male";
|
||||
})(Gender || (Gender = {}));
|
||||
//# sourceMappingURL=types.js.map
|
|
@ -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"}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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>;
|
||||
}
|
|
@ -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
|
File diff suppressed because one or more lines are too long
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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[];
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"FaceLandmarks.js","sourceRoot":"","sources":["../../src/classes/FaceLandmarks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAe,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAS,IAAI,EAAE,MAAM,QAAQ,CAAC;AAErC,2BAA2B;AAC3B,MAAM,IAAI,GAAG,GAAG,CAAA;AAChB,MAAM,IAAI,GAAG,IAAI,CAAA;AACjB,MAAM,QAAQ,GAAG,IAAI,CAAA;AAOrB,MAAM,OAAO,aAAa;IAKxB,YACE,6BAAsC,EACtC,OAAoB,EACpB,QAAe,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAE9B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;QACjC,IAAI,CAAC,QAAQ,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAC7C,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,UAAU,GAAG,6BAA6B,CAAC,GAAG,CACjD,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAClD,CAAA;IACH,CAAC;IAED,IAAW,KAAK,KAAY,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC;IAC5E,IAAW,UAAU,KAAa,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAA,CAAC,CAAC;IAC9D,IAAW,WAAW,KAAa,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAA,CAAC,CAAC;IAChE,IAAW,SAAS,KAAc,OAAO,IAAI,CAAC,UAAU,CAAA,CAAC,CAAC;IAC1D,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CACxB,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAC5E,CAAA;IACH,CAAC;IAEM,OAAO,CAA0B,KAAa,EAAE,MAAc;QACnE,OAAO,IAAK,IAAI,CAAC,WAAmB,CAClC,IAAI,CAAC,iBAAiB,EACtB,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAA;IACH,CAAC;IAEM,OAAO,CAA0B,CAAS,EAAE,CAAS;QAC1D,OAAO,IAAK,IAAI,CAAC,WAAmB,CAClC,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,QAAQ,EACb,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAChB,CAAA;IACH,CAAC;IAEM,YAAY,CAA0B,EAAS;QACpD,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IACjC,CAAC;IAED;;;;;;;;;;OAUG;IACI,KAAK,CACV,SAAuD,EACvD,UAAkE,EAAG;QAErE,IAAI,SAAS,EAAE;YACb,MAAM,GAAG,GAAG,SAAS,YAAY,aAAa;gBAC5C,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE;gBACvB,CAAC,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,CAAA;YAEtB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;SACvD;QAED,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,EAAE,OAAO,CAAC,CAAA;QAEvH,IAAI,gBAAgB,EAAE;YACpB,OAAO,IAAI,CAAC,SAAS,EAAE,CAAA;SACxB;QAED,OAAO,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAA;IACzC,CAAC;IAEO,SAAS;QAEf,MAAM,OAAO,GAAG,IAAI,CAAC,wBAAwB,EAAE,CAAA;QAE/C,MAAM,CAAC,aAAa,EAAE,cAAc,EAAE,WAAW,CAAC,GAAG,OAAO,CAAA;QAC5D,MAAM,WAAW,GAAG,CAAC,EAAS,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAA;QAClE,MAAM,cAAc,GAAG,CAAC,WAAW,CAAC,aAAa,CAAC,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAA;QAErF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,QAAQ,CAAC,CAAA;QAElD,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QACxC,qDAAqD;QACrD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QAC7D,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QAE7D,OAAO,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAA;IAClG,CAAC;IAEO,YAAY,CAAC,OAAe;QAClC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACnC,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,OAAO,EAAE,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,CAAA;IAC3D,CAAC;IAES,wBAAwB;QAChC,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAA;IAC3E,CAAC;CACF"}
|
|
@ -0,0 +1,5 @@
|
|||
import { FaceLandmarks } from './FaceLandmarks';
|
||||
import { Point } from './Point';
|
||||
export declare class FaceLandmarks5 extends FaceLandmarks {
|
||||
protected getRefPointsForAlignment(): Point[];
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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[];
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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"}
|
|
@ -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';
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
|
@ -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
|
|
@ -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"}
|
|
@ -0,0 +1,2 @@
|
|||
import { ParamMapping } from './types';
|
||||
export declare function disposeUnusedWeightTensors(weightMap: any, paramMappings: ParamMapping[]): void;
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
|
@ -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
|
|
@ -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"}
|
|
@ -0,0 +1,4 @@
|
|||
export declare function extractWeightsFactory(weights: Float32Array): {
|
||||
extractWeights: (numWeights: number) => Float32Array;
|
||||
getRemainingWeights: () => Float32Array;
|
||||
};
|
|
@ -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
|
|
@ -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"}
|
|
@ -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;
|
|
@ -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
|
|
@ -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"}
|
|
@ -0,0 +1,4 @@
|
|||
export declare function getModelUris(uri: string | undefined, defaultModelName: string): {
|
||||
modelBaseUri: string;
|
||||
manifestUri: string;
|
||||
};
|
|
@ -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
|
|
@ -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"}
|
|
@ -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';
|
|
@ -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
|
|
@ -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"}
|
|
@ -0,0 +1,2 @@
|
|||
import { ConvParams } from './types';
|
||||
export declare function loadConvParamsFactory(extractWeightEntry: <T>(originalPath: string, paramRank: number) => T): (prefix: string) => ConvParams;
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue