diff --git a/.gitignore b/.gitignore index dd87e2d..3c3629e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ node_modules -build diff --git a/build/NeuralNetwork.d.ts b/build/NeuralNetwork.d.ts new file mode 100644 index 0000000..273ab16 --- /dev/null +++ b/build/NeuralNetwork.d.ts @@ -0,0 +1,44 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { ParamMapping } from './common'; +export declare abstract class NeuralNetwork { + 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; + }[]; + getTrainableParams(): { + path: string; + tensor: tf.Tensor; + }[]; + getFrozenParams(): { + path: string; + tensor: tf.Tensor; + }[]; + variable(): void; + freeze(): void; + dispose(throwOnRedispose?: boolean): void; + serializeParams(): Float32Array; + load(weightsOrUrl: Float32Array | string | undefined): Promise; + loadFromUri(uri: string | undefined): Promise; + loadFromDisk(filePath: string | undefined): Promise; + 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[]; + }; +} diff --git a/build/NeuralNetwork.js b/build/NeuralNetwork.js new file mode 100644 index 0000000..9fe968e --- /dev/null +++ b/build/NeuralNetwork.js @@ -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 \ No newline at end of file diff --git a/build/NeuralNetwork.js.map b/build/NeuralNetwork.js.map new file mode 100644 index 0000000..274c0d8 --- /dev/null +++ b/build/NeuralNetwork.js.map @@ -0,0 +1 @@ +{"version":3,"file":"NeuralNetwork.js","sourceRoot":"","sources":["../src/NeuralNetwork.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/ageGenderNet/AgeGenderNet.d.ts b/build/ageGenderNet/AgeGenderNet.d.ts new file mode 100644 index 0000000..2bc29ca --- /dev/null +++ b/build/ageGenderNet/AgeGenderNet.d.ts @@ -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 { + private _faceFeatureExtractor; + constructor(faceFeatureExtractor?: TinyXception); + get faceFeatureExtractor(): TinyXception; + runNet(input: NetInput | tf.Tensor4D): NetOutput; + forwardInput(input: NetInput | tf.Tensor4D): NetOutput; + forward(input: TNetInput): Promise; + predictAgeAndGender(input: TNetInput): Promise; + 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[]; + }; +} diff --git a/build/ageGenderNet/AgeGenderNet.js b/build/ageGenderNet/AgeGenderNet.js new file mode 100644 index 0000000..eab848c --- /dev/null +++ b/build/ageGenderNet/AgeGenderNet.js @@ -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 \ No newline at end of file diff --git a/build/ageGenderNet/AgeGenderNet.js.map b/build/ageGenderNet/AgeGenderNet.js.map new file mode 100644 index 0000000..bceaba5 --- /dev/null +++ b/build/ageGenderNet/AgeGenderNet.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AgeGenderNet.js","sourceRoot":"","sources":["../../src/ageGenderNet/AgeGenderNet.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/ageGenderNet/extractParams.d.ts b/build/ageGenderNet/extractParams.d.ts new file mode 100644 index 0000000..f4e4b30 --- /dev/null +++ b/build/ageGenderNet/extractParams.d.ts @@ -0,0 +1,6 @@ +import { ParamMapping } from '../common'; +import { NetParams } from './types'; +export declare function extractParams(weights: Float32Array): { + params: NetParams; + paramMappings: ParamMapping[]; +}; diff --git a/build/ageGenderNet/extractParams.js b/build/ageGenderNet/extractParams.js new file mode 100644 index 0000000..c3201fe --- /dev/null +++ b/build/ageGenderNet/extractParams.js @@ -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 \ No newline at end of file diff --git a/build/ageGenderNet/extractParams.js.map b/build/ageGenderNet/extractParams.js.map new file mode 100644 index 0000000..12160f9 --- /dev/null +++ b/build/ageGenderNet/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"} \ No newline at end of file diff --git a/build/ageGenderNet/extractParamsFromWeigthMap.d.ts b/build/ageGenderNet/extractParamsFromWeigthMap.d.ts new file mode 100644 index 0000000..82627ad --- /dev/null +++ b/build/ageGenderNet/extractParamsFromWeigthMap.d.ts @@ -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[]; +}; diff --git a/build/ageGenderNet/extractParamsFromWeigthMap.js b/build/ageGenderNet/extractParamsFromWeigthMap.js new file mode 100644 index 0000000..58e0d84 --- /dev/null +++ b/build/ageGenderNet/extractParamsFromWeigthMap.js @@ -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 \ No newline at end of file diff --git a/build/ageGenderNet/extractParamsFromWeigthMap.js.map b/build/ageGenderNet/extractParamsFromWeigthMap.js.map new file mode 100644 index 0000000..df329f4 --- /dev/null +++ b/build/ageGenderNet/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"} \ No newline at end of file diff --git a/build/ageGenderNet/index.d.ts b/build/ageGenderNet/index.d.ts new file mode 100644 index 0000000..922b2de --- /dev/null +++ b/build/ageGenderNet/index.d.ts @@ -0,0 +1,2 @@ +export * from './AgeGenderNet'; +export * from './types'; diff --git a/build/ageGenderNet/index.js b/build/ageGenderNet/index.js new file mode 100644 index 0000000..6ef6393 --- /dev/null +++ b/build/ageGenderNet/index.js @@ -0,0 +1,3 @@ +export * from './AgeGenderNet'; +export * from './types'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/ageGenderNet/index.js.map b/build/ageGenderNet/index.js.map new file mode 100644 index 0000000..ede9f34 --- /dev/null +++ b/build/ageGenderNet/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"} \ No newline at end of file diff --git a/build/ageGenderNet/types.d.ts b/build/ageGenderNet/types.d.ts new file mode 100644 index 0000000..daf2c9b --- /dev/null +++ b/build/ageGenderNet/types.d.ts @@ -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; + }; +}; diff --git a/build/ageGenderNet/types.js b/build/ageGenderNet/types.js new file mode 100644 index 0000000..6808b5c --- /dev/null +++ b/build/ageGenderNet/types.js @@ -0,0 +1,6 @@ +export var Gender; +(function (Gender) { + Gender["FEMALE"] = "female"; + Gender["MALE"] = "male"; +})(Gender || (Gender = {})); +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/build/ageGenderNet/types.js.map b/build/ageGenderNet/types.js.map new file mode 100644 index 0000000..762fc2b --- /dev/null +++ b/build/ageGenderNet/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"} \ No newline at end of file diff --git a/build/classes/BoundingBox.d.ts b/build/classes/BoundingBox.d.ts new file mode 100644 index 0000000..7c5f096 --- /dev/null +++ b/build/classes/BoundingBox.d.ts @@ -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 implements IBoundingBox { + constructor(left: number, top: number, right: number, bottom: number, allowNegativeDimensions?: boolean); +} diff --git a/build/classes/BoundingBox.js b/build/classes/BoundingBox.js new file mode 100644 index 0000000..c7d5175 --- /dev/null +++ b/build/classes/BoundingBox.js @@ -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 \ No newline at end of file diff --git a/build/classes/BoundingBox.js.map b/build/classes/BoundingBox.js.map new file mode 100644 index 0000000..8a61988 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/Box.d.ts b/build/classes/Box.d.ts new file mode 100644 index 0000000..950f56a --- /dev/null +++ b/build/classes/Box.d.ts @@ -0,0 +1,46 @@ +import { IBoundingBox } from './BoundingBox'; +import { IDimensions } from './Dimensions'; +import { Point } from './Point'; +import { IRect } from './Rect'; +export declare class Box 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; + floor(): Box; + toSquare(): Box; + rescale(s: IDimensions | number): Box; + pad(padX: number, padY: number): Box; + clipAtImageBorders(imgWidth: number, imgHeight: number): Box; + shift(sx: number, sy: number): Box; + 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; +} diff --git a/build/classes/Box.js b/build/classes/Box.js new file mode 100644 index 0000000..df4affa --- /dev/null +++ b/build/classes/Box.js @@ -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 \ No newline at end of file diff --git a/build/classes/Box.js.map b/build/classes/Box.js.map new file mode 100644 index 0000000..54d5794 --- /dev/null +++ b/build/classes/Box.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Box.js","sourceRoot":"","sources":["../../src/classes/Box.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGvD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,MAAM,OAAO,GAAG;IAqBd,YAAY,IAA0B,EAAE,0BAAmC,IAAI;QAC7E,MAAM,GAAG,GAAG,CAAC,IAAI,IAAI,EAAE,CAAQ,CAAA;QAE/B,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;QAC9E,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;QAEzE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,2EAA2E,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;SAClH;QAED,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM;YAClC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC;YACvC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;QAEnE,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,iBAAiB,EAAE,uBAAuB,CAAC,CAAA;QAEzF,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;QACX,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;QACX,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;IACvB,CAAC;IAvCM,MAAM,CAAC,MAAM,CAAC,IAAS;QAC5B,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;IACjF,CAAC;IAEM,MAAM,CAAC,gBAAgB,CAAC,GAAQ,EAAE,MAAc,EAAE,0BAAmC,KAAK;QAC/F,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;YACpB,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,mBAAmB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAA;SACxH;QAED,IAAI,CAAC,uBAAuB,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;YACjE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,aAAa,GAAG,CAAC,KAAK,iBAAiB,GAAG,CAAC,MAAM,4BAA4B,CAAC,CAAA;SACxG;IACH,CAAC;IA6BD,IAAW,CAAC,KAAa,OAAO,IAAI,CAAC,EAAE,CAAA,CAAC,CAAC;IACzC,IAAW,CAAC,KAAa,OAAO,IAAI,CAAC,EAAE,CAAA,CAAC,CAAC;IACzC,IAAW,KAAK,KAAa,OAAO,IAAI,CAAC,MAAM,CAAA,CAAC,CAAC;IACjD,IAAW,MAAM,KAAa,OAAO,IAAI,CAAC,OAAO,CAAA,CAAC,CAAC;IACnD,IAAW,IAAI,KAAa,OAAO,IAAI,CAAC,CAAC,CAAA,CAAC,CAAC;IAC3C,IAAW,GAAG,KAAa,OAAO,IAAI,CAAC,CAAC,CAAA,CAAC,CAAC;IAC1C,IAAW,KAAK,KAAa,OAAO,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAA,CAAC,CAAC;IACzD,IAAW,MAAM,KAAa,OAAO,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAA,CAAC,CAAC;IAC3D,IAAW,IAAI,KAAa,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAA,CAAC,CAAC;IAC7D,IAAW,OAAO,KAAY,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA,CAAC,CAAC;IACrE,IAAW,QAAQ,KAAY,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA,CAAC,CAAC;IACvE,IAAW,UAAU,KAAY,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA,CAAC,CAAC;IAC3E,IAAW,WAAW,KAAY,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA,CAAC,CAAC;IAEtE,KAAK;QACV,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;aACpE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;QAC9B,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IACzC,CAAC;IAEM,KAAK;QACV,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;aACpE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;QAC9B,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IACzC,CAAC;IAEM,QAAQ;QACb,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,CAAA;QACrC,IAAI,KAAK,GAAG,MAAM,EAAE;YAClB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;YACf,KAAK,IAAI,IAAI,CAAA;SACd;QACD,IAAI,MAAM,GAAG,KAAK,EAAE;YAClB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;YACf,MAAM,IAAI,IAAI,CAAA;SACf;QAED,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IACzC,CAAC;IAEM,OAAO,CAAC,CAAuB;QACpC,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAW,CAAA;QACvE,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAW,CAAA;QACxE,OAAO,IAAI,GAAG,CAAC;YACb,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,MAAM;YAClB,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,MAAM;YAClB,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,MAAM;YAC1B,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,MAAM;SAC7B,CAAC,CAAA;IACJ,CAAC;IAEM,GAAG,CAAC,IAAY,EAAE,IAAY;QACnC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG;YAC1B,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;YACnB,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;YACnB,IAAI,CAAC,KAAK,GAAG,IAAI;YACjB,IAAI,CAAC,MAAM,GAAG,IAAI;SACnB,CAAA;QACD,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IACzC,CAAC;IAEM,kBAAkB,CAAC,QAAgB,EAAE,SAAiB;QAC3D,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAE/B,MAAM,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAA;QACjC,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAA;QACnC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,CAAA;QAC5D,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAA;QAE/D,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAA;IACnG,CAAC;IAEM,KAAK,CAAC,EAAU,EAAE,EAAU;QACjC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;QAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAA;QACrB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAA;QAErB,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IACzC,CAAC;IAEM,YAAY,CAAC,WAAmB,EAAE,UAAkB;QACzD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAA;QACxB,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAA;QAEzB,IAAI,EAAE,GAAG,CAAC,CAAA;QACV,IAAI,EAAE,GAAG,CAAC,CAAA;QACV,IAAI,GAAG,GAAG,CAAC,CAAA;QACX,IAAI,GAAG,GAAG,CAAC,CAAA;QAEX,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAA;QACjB,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAA;QAChB,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QACnB,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAEpB,IAAI,EAAE,GAAG,UAAU,EAAE;YACnB,GAAG,GAAG,CAAC,EAAE,GAAG,UAAU,GAAG,CAAC,CAAA;YAC1B,EAAE,GAAG,UAAU,CAAA;SAChB;QACD,IAAI,EAAE,GAAG,WAAW,EAAE;YACpB,GAAG,GAAG,CAAC,EAAE,GAAG,WAAW,GAAG,CAAC,CAAA;YAC3B,EAAE,GAAG,WAAW,CAAA;SACjB;QACD,IAAI,CAAC,GAAG,CAAC,EAAE;YACT,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;YACX,CAAC,GAAG,CAAC,CAAA;SACN;QACD,IAAI,CAAC,GAAG,CAAC,EAAE;YACT,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;YACX,CAAC,GAAG,CAAC,CAAA;SACN;QAED,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;IACjD,CAAC;IAEM,SAAS,CAAC,MAAW;QAC1B,OAAO,IAAI,GAAG,CAAC;YACb,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;YAC5C,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YAC/C,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;SACpD,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAA;IACvB,CAAC;CACF"} \ No newline at end of file diff --git a/build/classes/Dimensions.d.ts b/build/classes/Dimensions.d.ts new file mode 100644 index 0000000..fe169cc --- /dev/null +++ b/build/classes/Dimensions.d.ts @@ -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; +} diff --git a/build/classes/Dimensions.js b/build/classes/Dimensions.js new file mode 100644 index 0000000..02482c8 --- /dev/null +++ b/build/classes/Dimensions.js @@ -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 \ No newline at end of file diff --git a/build/classes/Dimensions.js.map b/build/classes/Dimensions.js.map new file mode 100644 index 0000000..bfe6d12 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/FaceDetection.d.ts b/build/classes/FaceDetection.d.ts new file mode 100644 index 0000000..5377318 --- /dev/null +++ b/build/classes/FaceDetection.d.ts @@ -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; +} diff --git a/build/classes/FaceDetection.js b/build/classes/FaceDetection.js new file mode 100644 index 0000000..e685cdf --- /dev/null +++ b/build/classes/FaceDetection.js @@ -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 \ No newline at end of file diff --git a/build/classes/FaceDetection.js.map b/build/classes/FaceDetection.js.map new file mode 100644 index 0000000..9d44742 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/FaceLandmarks.d.ts b/build/classes/FaceLandmarks.d.ts new file mode 100644 index 0000000..ead3ca9 --- /dev/null +++ b/build/classes/FaceLandmarks.d.ts @@ -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(width: number, height: number): T; + shiftBy(x: number, y: number): T; + shiftByPoint(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[]; +} diff --git a/build/classes/FaceLandmarks.js b/build/classes/FaceLandmarks.js new file mode 100644 index 0000000..cb83e12 --- /dev/null +++ b/build/classes/FaceLandmarks.js @@ -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 \ No newline at end of file diff --git a/build/classes/FaceLandmarks.js.map b/build/classes/FaceLandmarks.js.map new file mode 100644 index 0000000..c9efbf1 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/FaceLandmarks5.d.ts b/build/classes/FaceLandmarks5.d.ts new file mode 100644 index 0000000..e514bcf --- /dev/null +++ b/build/classes/FaceLandmarks5.d.ts @@ -0,0 +1,5 @@ +import { FaceLandmarks } from './FaceLandmarks'; +import { Point } from './Point'; +export declare class FaceLandmarks5 extends FaceLandmarks { + protected getRefPointsForAlignment(): Point[]; +} diff --git a/build/classes/FaceLandmarks5.js b/build/classes/FaceLandmarks5.js new file mode 100644 index 0000000..4f4d6f0 --- /dev/null +++ b/build/classes/FaceLandmarks5.js @@ -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 \ No newline at end of file diff --git a/build/classes/FaceLandmarks5.js.map b/build/classes/FaceLandmarks5.js.map new file mode 100644 index 0000000..45742b8 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/FaceLandmarks68.d.ts b/build/classes/FaceLandmarks68.d.ts new file mode 100644 index 0000000..dce3ba5 --- /dev/null +++ b/build/classes/FaceLandmarks68.d.ts @@ -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[]; +} diff --git a/build/classes/FaceLandmarks68.js b/build/classes/FaceLandmarks68.js new file mode 100644 index 0000000..b802995 --- /dev/null +++ b/build/classes/FaceLandmarks68.js @@ -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 \ No newline at end of file diff --git a/build/classes/FaceLandmarks68.js.map b/build/classes/FaceLandmarks68.js.map new file mode 100644 index 0000000..81207b8 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/FaceMatch.d.ts b/build/classes/FaceMatch.d.ts new file mode 100644 index 0000000..01e4a27 --- /dev/null +++ b/build/classes/FaceMatch.d.ts @@ -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; +} diff --git a/build/classes/FaceMatch.js b/build/classes/FaceMatch.js new file mode 100644 index 0000000..1a3cf1f --- /dev/null +++ b/build/classes/FaceMatch.js @@ -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 \ No newline at end of file diff --git a/build/classes/FaceMatch.js.map b/build/classes/FaceMatch.js.map new file mode 100644 index 0000000..5db9542 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/LabeledBox.d.ts b/build/classes/LabeledBox.d.ts new file mode 100644 index 0000000..6cf39c0 --- /dev/null +++ b/build/classes/LabeledBox.d.ts @@ -0,0 +1,9 @@ +import { IBoundingBox } from './BoundingBox'; +import { Box } from './Box'; +import { IRect } from './Rect'; +export declare class LabeledBox extends Box { + static assertIsValidLabeledBox(box: any, callee: string): void; + private _label; + constructor(box: IBoundingBox | IRect | any, label: number); + get label(): number; +} diff --git a/build/classes/LabeledBox.js b/build/classes/LabeledBox.js new file mode 100644 index 0000000..49f2579 --- /dev/null +++ b/build/classes/LabeledBox.js @@ -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 \ No newline at end of file diff --git a/build/classes/LabeledBox.js.map b/build/classes/LabeledBox.js.map new file mode 100644 index 0000000..8b65e62 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/LabeledFaceDescriptors.d.ts b/build/classes/LabeledFaceDescriptors.d.ts new file mode 100644 index 0000000..6015429 --- /dev/null +++ b/build/classes/LabeledFaceDescriptors.d.ts @@ -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; +} diff --git a/build/classes/LabeledFaceDescriptors.js b/build/classes/LabeledFaceDescriptors.js new file mode 100644 index 0000000..c41093f --- /dev/null +++ b/build/classes/LabeledFaceDescriptors.js @@ -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 \ No newline at end of file diff --git a/build/classes/LabeledFaceDescriptors.js.map b/build/classes/LabeledFaceDescriptors.js.map new file mode 100644 index 0000000..1fe1609 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/ObjectDetection.d.ts b/build/classes/ObjectDetection.d.ts new file mode 100644 index 0000000..feae090 --- /dev/null +++ b/build/classes/ObjectDetection.d.ts @@ -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; +} diff --git a/build/classes/ObjectDetection.js b/build/classes/ObjectDetection.js new file mode 100644 index 0000000..b4af12d --- /dev/null +++ b/build/classes/ObjectDetection.js @@ -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 \ No newline at end of file diff --git a/build/classes/ObjectDetection.js.map b/build/classes/ObjectDetection.js.map new file mode 100644 index 0000000..8e8f888 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/Point.d.ts b/build/classes/Point.d.ts new file mode 100644 index 0000000..2c330fb --- /dev/null +++ b/build/classes/Point.d.ts @@ -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; +} diff --git a/build/classes/Point.js b/build/classes/Point.js new file mode 100644 index 0000000..1cd1ac0 --- /dev/null +++ b/build/classes/Point.js @@ -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 \ No newline at end of file diff --git a/build/classes/Point.js.map b/build/classes/Point.js.map new file mode 100644 index 0000000..9e94353 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/PredictedBox.d.ts b/build/classes/PredictedBox.d.ts new file mode 100644 index 0000000..8a72117 --- /dev/null +++ b/build/classes/PredictedBox.d.ts @@ -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; +} diff --git a/build/classes/PredictedBox.js b/build/classes/PredictedBox.js new file mode 100644 index 0000000..ad33c9c --- /dev/null +++ b/build/classes/PredictedBox.js @@ -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 \ No newline at end of file diff --git a/build/classes/PredictedBox.js.map b/build/classes/PredictedBox.js.map new file mode 100644 index 0000000..d08214a --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/Rect.d.ts b/build/classes/Rect.d.ts new file mode 100644 index 0000000..c88c89a --- /dev/null +++ b/build/classes/Rect.d.ts @@ -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 implements IRect { + constructor(x: number, y: number, width: number, height: number, allowNegativeDimensions?: boolean); +} diff --git a/build/classes/Rect.js b/build/classes/Rect.js new file mode 100644 index 0000000..711acfd --- /dev/null +++ b/build/classes/Rect.js @@ -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 \ No newline at end of file diff --git a/build/classes/Rect.js.map b/build/classes/Rect.js.map new file mode 100644 index 0000000..d7e1adf --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/classes/index.d.ts b/build/classes/index.d.ts new file mode 100644 index 0000000..b66b71e --- /dev/null +++ b/build/classes/index.d.ts @@ -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'; diff --git a/build/classes/index.js b/build/classes/index.js new file mode 100644 index 0000000..a6d936b --- /dev/null +++ b/build/classes/index.js @@ -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 \ No newline at end of file diff --git a/build/classes/index.js.map b/build/classes/index.js.map new file mode 100644 index 0000000..cb05ee0 --- /dev/null +++ b/build/classes/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"} \ No newline at end of file diff --git a/build/common/convLayer.d.ts b/build/common/convLayer.d.ts new file mode 100644 index 0000000..e0b77a3 --- /dev/null +++ b/build/common/convLayer.d.ts @@ -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; diff --git a/build/common/convLayer.js b/build/common/convLayer.js new file mode 100644 index 0000000..411439a --- /dev/null +++ b/build/common/convLayer.js @@ -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 \ No newline at end of file diff --git a/build/common/convLayer.js.map b/build/common/convLayer.js.map new file mode 100644 index 0000000..c148fa0 --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/depthwiseSeparableConv.d.ts b/build/common/depthwiseSeparableConv.d.ts new file mode 100644 index 0000000..0725c45 --- /dev/null +++ b/build/common/depthwiseSeparableConv.d.ts @@ -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; diff --git a/build/common/depthwiseSeparableConv.js b/build/common/depthwiseSeparableConv.js new file mode 100644 index 0000000..a91a632 --- /dev/null +++ b/build/common/depthwiseSeparableConv.js @@ -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 \ No newline at end of file diff --git a/build/common/depthwiseSeparableConv.js.map b/build/common/depthwiseSeparableConv.js.map new file mode 100644 index 0000000..de28b10 --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/disposeUnusedWeightTensors.d.ts b/build/common/disposeUnusedWeightTensors.d.ts new file mode 100644 index 0000000..927401b --- /dev/null +++ b/build/common/disposeUnusedWeightTensors.d.ts @@ -0,0 +1,2 @@ +import { ParamMapping } from './types'; +export declare function disposeUnusedWeightTensors(weightMap: any, paramMappings: ParamMapping[]): void; diff --git a/build/common/disposeUnusedWeightTensors.js b/build/common/disposeUnusedWeightTensors.js new file mode 100644 index 0000000..08a5c61 --- /dev/null +++ b/build/common/disposeUnusedWeightTensors.js @@ -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 \ No newline at end of file diff --git a/build/common/disposeUnusedWeightTensors.js.map b/build/common/disposeUnusedWeightTensors.js.map new file mode 100644 index 0000000..b917cd1 --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/extractConvParamsFactory.d.ts b/build/common/extractConvParamsFactory.d.ts new file mode 100644 index 0000000..03908f7 --- /dev/null +++ b/build/common/extractConvParamsFactory.d.ts @@ -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; diff --git a/build/common/extractConvParamsFactory.js b/build/common/extractConvParamsFactory.js new file mode 100644 index 0000000..5aec5cd --- /dev/null +++ b/build/common/extractConvParamsFactory.js @@ -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 \ No newline at end of file diff --git a/build/common/extractConvParamsFactory.js.map b/build/common/extractConvParamsFactory.js.map new file mode 100644 index 0000000..1668983 --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/extractFCParamsFactory.d.ts b/build/common/extractFCParamsFactory.d.ts new file mode 100644 index 0000000..173afc4 --- /dev/null +++ b/build/common/extractFCParamsFactory.d.ts @@ -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; diff --git a/build/common/extractFCParamsFactory.js b/build/common/extractFCParamsFactory.js new file mode 100644 index 0000000..0065198 --- /dev/null +++ b/build/common/extractFCParamsFactory.js @@ -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 \ No newline at end of file diff --git a/build/common/extractFCParamsFactory.js.map b/build/common/extractFCParamsFactory.js.map new file mode 100644 index 0000000..ab9eed4 --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/extractSeparableConvParamsFactory.d.ts b/build/common/extractSeparableConvParamsFactory.d.ts new file mode 100644 index 0000000..1e20f3b --- /dev/null +++ b/build/common/extractSeparableConvParamsFactory.d.ts @@ -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: (originalPath: string, paramRank: number) => T): (prefix: string) => SeparableConvParams; diff --git a/build/common/extractSeparableConvParamsFactory.js b/build/common/extractSeparableConvParamsFactory.js new file mode 100644 index 0000000..5d9a7a8 --- /dev/null +++ b/build/common/extractSeparableConvParamsFactory.js @@ -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 \ No newline at end of file diff --git a/build/common/extractSeparableConvParamsFactory.js.map b/build/common/extractSeparableConvParamsFactory.js.map new file mode 100644 index 0000000..b173824 --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/extractWeightEntryFactory.d.ts b/build/common/extractWeightEntryFactory.d.ts new file mode 100644 index 0000000..b532003 --- /dev/null +++ b/build/common/extractWeightEntryFactory.d.ts @@ -0,0 +1,2 @@ +import { ParamMapping } from './types'; +export declare function extractWeightEntryFactory(weightMap: any, paramMappings: ParamMapping[]): (originalPath: string, paramRank: number, mappedPath?: string | undefined) => T; diff --git a/build/common/extractWeightEntryFactory.js b/build/common/extractWeightEntryFactory.js new file mode 100644 index 0000000..6a87e33 --- /dev/null +++ b/build/common/extractWeightEntryFactory.js @@ -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 \ No newline at end of file diff --git a/build/common/extractWeightEntryFactory.js.map b/build/common/extractWeightEntryFactory.js.map new file mode 100644 index 0000000..f335393 --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/extractWeightsFactory.d.ts b/build/common/extractWeightsFactory.d.ts new file mode 100644 index 0000000..baf2ef9 --- /dev/null +++ b/build/common/extractWeightsFactory.d.ts @@ -0,0 +1,4 @@ +export declare function extractWeightsFactory(weights: Float32Array): { + extractWeights: (numWeights: number) => Float32Array; + getRemainingWeights: () => Float32Array; +}; diff --git a/build/common/extractWeightsFactory.js b/build/common/extractWeightsFactory.js new file mode 100644 index 0000000..0bd2890 --- /dev/null +++ b/build/common/extractWeightsFactory.js @@ -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 \ No newline at end of file diff --git a/build/common/extractWeightsFactory.js.map b/build/common/extractWeightsFactory.js.map new file mode 100644 index 0000000..18852fd --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/fullyConnectedLayer.d.ts b/build/common/fullyConnectedLayer.d.ts new file mode 100644 index 0000000..4a3aa90 --- /dev/null +++ b/build/common/fullyConnectedLayer.d.ts @@ -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; diff --git a/build/common/fullyConnectedLayer.js b/build/common/fullyConnectedLayer.js new file mode 100644 index 0000000..9ac4178 --- /dev/null +++ b/build/common/fullyConnectedLayer.js @@ -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 \ No newline at end of file diff --git a/build/common/fullyConnectedLayer.js.map b/build/common/fullyConnectedLayer.js.map new file mode 100644 index 0000000..450db69 --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/getModelUris.d.ts b/build/common/getModelUris.d.ts new file mode 100644 index 0000000..9a5f64a --- /dev/null +++ b/build/common/getModelUris.d.ts @@ -0,0 +1,4 @@ +export declare function getModelUris(uri: string | undefined, defaultModelName: string): { + modelBaseUri: string; + manifestUri: string; +}; diff --git a/build/common/getModelUris.js b/build/common/getModelUris.js new file mode 100644 index 0000000..f532647 --- /dev/null +++ b/build/common/getModelUris.js @@ -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 \ No newline at end of file diff --git a/build/common/getModelUris.js.map b/build/common/getModelUris.js.map new file mode 100644 index 0000000..c126833 --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/index.d.ts b/build/common/index.d.ts new file mode 100644 index 0000000..fc307a0 --- /dev/null +++ b/build/common/index.d.ts @@ -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'; diff --git a/build/common/index.js b/build/common/index.js new file mode 100644 index 0000000..fc1aa0f --- /dev/null +++ b/build/common/index.js @@ -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 \ No newline at end of file diff --git a/build/common/index.js.map b/build/common/index.js.map new file mode 100644 index 0000000..88dbe26 --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/loadConvParamsFactory.d.ts b/build/common/loadConvParamsFactory.d.ts new file mode 100644 index 0000000..c139c7b --- /dev/null +++ b/build/common/loadConvParamsFactory.d.ts @@ -0,0 +1,2 @@ +import { ConvParams } from './types'; +export declare function loadConvParamsFactory(extractWeightEntry: (originalPath: string, paramRank: number) => T): (prefix: string) => ConvParams; diff --git a/build/common/loadConvParamsFactory.js b/build/common/loadConvParamsFactory.js new file mode 100644 index 0000000..88f1b7a --- /dev/null +++ b/build/common/loadConvParamsFactory.js @@ -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 \ No newline at end of file diff --git a/build/common/loadConvParamsFactory.js.map b/build/common/loadConvParamsFactory.js.map new file mode 100644 index 0000000..2207c63 --- /dev/null +++ b/build/common/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"} \ No newline at end of file diff --git a/build/common/types.d.ts b/build/common/types.d.ts new file mode 100644 index 0000000..7a8bfd4 --- /dev/null +++ b/build/common/types.d.ts @@ -0,0 +1,20 @@ +import * as tf from '@tensorflow/tfjs-core'; +export declare type ExtractWeightsFunction = (numWeights: number) => Float32Array; +export declare type ParamMapping = { + originalPath?: string; + paramPath: string; +}; +export declare type ConvParams = { + filters: tf.Tensor4D; + bias: tf.Tensor1D; +}; +export declare type FCParams = { + weights: tf.Tensor2D; + bias: tf.Tensor1D; +}; +export declare class SeparableConvParams { + depthwise_filter: tf.Tensor4D; + pointwise_filter: tf.Tensor4D; + bias: tf.Tensor1D; + constructor(depthwise_filter: tf.Tensor4D, pointwise_filter: tf.Tensor4D, bias: tf.Tensor1D); +} diff --git a/build/common/types.js b/build/common/types.js new file mode 100644 index 0000000..b1cb624 --- /dev/null +++ b/build/common/types.js @@ -0,0 +1,8 @@ +export class SeparableConvParams { + constructor(depthwise_filter, pointwise_filter, bias) { + this.depthwise_filter = depthwise_filter; + this.pointwise_filter = pointwise_filter; + this.bias = bias; + } +} +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/build/common/types.js.map b/build/common/types.js.map new file mode 100644 index 0000000..72e0e1f --- /dev/null +++ b/build/common/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"AAmBA,MAAM,OAAO,mBAAmB;IAC9B,YACS,gBAA6B,EAC7B,gBAA6B,EAC7B,IAAiB;QAFjB,qBAAgB,GAAhB,gBAAgB,CAAa;QAC7B,qBAAgB,GAAhB,gBAAgB,CAAa;QAC7B,SAAI,GAAJ,IAAI,CAAa;IACvB,CAAC;CACL"} \ No newline at end of file diff --git a/build/dom/NetInput.d.ts b/build/dom/NetInput.d.ts new file mode 100644 index 0000000..64d83ba --- /dev/null +++ b/build/dom/NetInput.d.ts @@ -0,0 +1,34 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { Dimensions } from '../classes/Dimensions'; +import { TResolvedNetInput } from './types'; +export declare class NetInput { + private _imageTensors; + private _canvases; + private _batchSize; + private _treatAsBatchInput; + private _inputDimensions; + private _inputSize; + constructor(inputs: Array, treatAsBatchInput?: boolean); + get imageTensors(): Array; + get canvases(): HTMLCanvasElement[]; + get isBatchInput(): boolean; + get batchSize(): number; + get inputDimensions(): number[][]; + get inputSize(): number | undefined; + get reshapedInputDimensions(): Dimensions[]; + getInput(batchIdx: number): tf.Tensor3D | tf.Tensor4D | HTMLCanvasElement; + getInputDimensions(batchIdx: number): number[]; + getInputHeight(batchIdx: number): number; + getInputWidth(batchIdx: number): number; + getReshapedInputDimensions(batchIdx: number): Dimensions; + /** + * Create a batch tensor from all input canvases and tensors + * with size [batchSize, inputSize, inputSize, 3]. + * + * @param inputSize Height and width of the tensor. + * @param isCenterImage (optional, default: false) If true, add an equal amount of padding on + * both sides of the minor dimension oof the image. + * @returns The batch tensor. + */ + toBatchTensor(inputSize: number, isCenterInputs?: boolean): tf.Tensor4D; +} diff --git a/build/dom/NetInput.js b/build/dom/NetInput.js new file mode 100644 index 0000000..a154818 --- /dev/null +++ b/build/dom/NetInput.js @@ -0,0 +1,113 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { env } from '../env'; +import { padToSquare } from '../ops/padToSquare'; +import { computeReshapedDimensions, isTensor3D, isTensor4D, range } from '../utils'; +import { createCanvasFromMedia } from './createCanvas'; +import { imageToSquare } from './imageToSquare'; +export class NetInput { + constructor(inputs, treatAsBatchInput = false) { + this._imageTensors = []; + this._canvases = []; + this._treatAsBatchInput = false; + this._inputDimensions = []; + if (!Array.isArray(inputs)) { + throw new Error(`NetInput.constructor - expected inputs to be an Array of TResolvedNetInput or to be instanceof tf.Tensor4D, instead have ${inputs}`); + } + this._treatAsBatchInput = treatAsBatchInput; + this._batchSize = inputs.length; + inputs.forEach((input, idx) => { + if (isTensor3D(input)) { + this._imageTensors[idx] = input; + this._inputDimensions[idx] = input.shape; + return; + } + if (isTensor4D(input)) { + const batchSize = input.shape[0]; + if (batchSize !== 1) { + throw new Error(`NetInput - tf.Tensor4D with batchSize ${batchSize} passed, but not supported in input array`); + } + this._imageTensors[idx] = input; + this._inputDimensions[idx] = input.shape.slice(1); + return; + } + const canvas = input instanceof env.getEnv().Canvas ? input : createCanvasFromMedia(input); + this._canvases[idx] = canvas; + this._inputDimensions[idx] = [canvas.height, canvas.width, 3]; + }); + } + get imageTensors() { + return this._imageTensors; + } + get canvases() { + return this._canvases; + } + get isBatchInput() { + return this.batchSize > 1 || this._treatAsBatchInput; + } + get batchSize() { + return this._batchSize; + } + get inputDimensions() { + return this._inputDimensions; + } + get inputSize() { + return this._inputSize; + } + get reshapedInputDimensions() { + return range(this.batchSize, 0, 1).map((_, batchIdx) => this.getReshapedInputDimensions(batchIdx)); + } + getInput(batchIdx) { + return this.canvases[batchIdx] || this.imageTensors[batchIdx]; + } + getInputDimensions(batchIdx) { + return this._inputDimensions[batchIdx]; + } + getInputHeight(batchIdx) { + return this._inputDimensions[batchIdx][0]; + } + getInputWidth(batchIdx) { + return this._inputDimensions[batchIdx][1]; + } + getReshapedInputDimensions(batchIdx) { + if (typeof this.inputSize !== 'number') { + throw new Error('getReshapedInputDimensions - inputSize not set, toBatchTensor has not been called yet'); + } + const width = this.getInputWidth(batchIdx); + const height = this.getInputHeight(batchIdx); + return computeReshapedDimensions({ width, height }, this.inputSize); + } + /** + * Create a batch tensor from all input canvases and tensors + * with size [batchSize, inputSize, inputSize, 3]. + * + * @param inputSize Height and width of the tensor. + * @param isCenterImage (optional, default: false) If true, add an equal amount of padding on + * both sides of the minor dimension oof the image. + * @returns The batch tensor. + */ + toBatchTensor(inputSize, isCenterInputs = true) { + this._inputSize = inputSize; + return tf.tidy(() => { + const inputTensors = range(this.batchSize, 0, 1).map(batchIdx => { + const input = this.getInput(batchIdx); + if (input instanceof tf.Tensor) { + // @ts-ignore: error TS2344: Type 'Rank.R4' does not satisfy the constraint 'Tensor'. + let imgTensor = isTensor4D(input) ? input : input.expandDims(); + // @ts-ignore: error TS2344: Type 'Rank.R4' does not satisfy the constraint 'Tensor'. + imgTensor = padToSquare(imgTensor, isCenterInputs); + if (imgTensor.shape[1] !== inputSize || imgTensor.shape[2] !== inputSize) { + imgTensor = tf.image.resizeBilinear(imgTensor, [inputSize, inputSize]); + } + return imgTensor.as3D(inputSize, inputSize, 3); + } + if (input instanceof env.getEnv().Canvas) { + return tf.browser.fromPixels(imageToSquare(input, inputSize, isCenterInputs)); + } + throw new Error(`toBatchTensor - at batchIdx ${batchIdx}, expected input to be instanceof tf.Tensor or instanceof HTMLCanvasElement, instead have ${input}`); + }); + const batchTensor = tf.stack(inputTensors.map(t => t.toFloat())).as4D(this.batchSize, inputSize, inputSize, 3); + return batchTensor; + }); + } +} +//# sourceMappingURL=NetInput.js.map \ No newline at end of file diff --git a/build/dom/NetInput.js.map b/build/dom/NetInput.js.map new file mode 100644 index 0000000..82d2a5b --- /dev/null +++ b/build/dom/NetInput.js.map @@ -0,0 +1 @@ +{"version":3,"file":"NetInput.js","sourceRoot":"","sources":["../../src/dom/NetInput.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/dom/awaitMediaLoaded.d.ts b/build/dom/awaitMediaLoaded.d.ts new file mode 100644 index 0000000..d8eca6a --- /dev/null +++ b/build/dom/awaitMediaLoaded.d.ts @@ -0,0 +1 @@ +export declare function awaitMediaLoaded(media: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement): Promise; diff --git a/build/dom/awaitMediaLoaded.js b/build/dom/awaitMediaLoaded.js new file mode 100644 index 0000000..ce81493 --- /dev/null +++ b/build/dom/awaitMediaLoaded.js @@ -0,0 +1,26 @@ +import { env } from '../env'; +import { isMediaLoaded } from './isMediaLoaded'; +export function awaitMediaLoaded(media) { + return new Promise((resolve, reject) => { + if (media instanceof env.getEnv().Canvas || isMediaLoaded(media)) { + return resolve(); + } + function onLoad(e) { + if (!e.currentTarget) + return; + e.currentTarget.removeEventListener('load', onLoad); + e.currentTarget.removeEventListener('error', onError); + resolve(e); + } + function onError(e) { + if (!e.currentTarget) + return; + e.currentTarget.removeEventListener('load', onLoad); + e.currentTarget.removeEventListener('error', onError); + reject(e); + } + media.addEventListener('load', onLoad); + media.addEventListener('error', onError); + }); +} +//# sourceMappingURL=awaitMediaLoaded.js.map \ No newline at end of file diff --git a/build/dom/awaitMediaLoaded.js.map b/build/dom/awaitMediaLoaded.js.map new file mode 100644 index 0000000..f2f9db6 --- /dev/null +++ b/build/dom/awaitMediaLoaded.js.map @@ -0,0 +1 @@ +{"version":3,"file":"awaitMediaLoaded.js","sourceRoot":"","sources":["../../src/dom/awaitMediaLoaded.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,UAAU,gBAAgB,CAAC,KAA8D;IAE7F,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,KAAK,YAAY,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE;YAChE,OAAO,OAAO,EAAE,CAAA;SACjB;QAED,SAAS,MAAM,CAAC,CAAQ;YACtB,IAAI,CAAC,CAAC,CAAC,aAAa;gBAAE,OAAM;YAC5B,CAAC,CAAC,aAAa,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;YACnD,CAAC,CAAC,aAAa,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YACrD,OAAO,CAAC,CAAC,CAAC,CAAA;QACZ,CAAC;QAED,SAAS,OAAO,CAAC,CAAQ;YACvB,IAAI,CAAC,CAAC,CAAC,aAAa;gBAAE,OAAM;YAC5B,CAAC,CAAC,aAAa,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;YACnD,CAAC,CAAC,aAAa,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YACrD,MAAM,CAAC,CAAC,CAAC,CAAA;QACX,CAAC;QAED,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACtC,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/dom/bufferToImage.d.ts b/build/dom/bufferToImage.d.ts new file mode 100644 index 0000000..f153ac7 --- /dev/null +++ b/build/dom/bufferToImage.d.ts @@ -0,0 +1 @@ +export declare function bufferToImage(buf: Blob): Promise; diff --git a/build/dom/bufferToImage.js b/build/dom/bufferToImage.js new file mode 100644 index 0000000..1395413 --- /dev/null +++ b/build/dom/bufferToImage.js @@ -0,0 +1,21 @@ +import { env } from '../env'; +export function bufferToImage(buf) { + return new Promise((resolve, reject) => { + if (!(buf instanceof Blob)) { + return reject('bufferToImage - expected buf to be of type: Blob'); + } + const reader = new FileReader(); + reader.onload = () => { + if (typeof reader.result !== 'string') { + return reject('bufferToImage - expected reader.result to be a string, in onload'); + } + const img = env.getEnv().createImageElement(); + img.onload = () => resolve(img); + img.onerror = reject; + img.src = reader.result; + }; + reader.onerror = reject; + reader.readAsDataURL(buf); + }); +} +//# sourceMappingURL=bufferToImage.js.map \ No newline at end of file diff --git a/build/dom/bufferToImage.js.map b/build/dom/bufferToImage.js.map new file mode 100644 index 0000000..61088f4 --- /dev/null +++ b/build/dom/bufferToImage.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bufferToImage.js","sourceRoot":"","sources":["../../src/dom/bufferToImage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAE7B,MAAM,UAAU,aAAa,CAAC,GAAS;IACrC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC,EAAE;YAC1B,OAAO,MAAM,CAAC,kDAAkD,CAAC,CAAA;SAClE;QAED,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAA;QAC/B,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE;YACnB,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE;gBACrC,OAAO,MAAM,CAAC,kEAAkE,CAAC,CAAA;aAClF;YAED,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,kBAAkB,EAAE,CAAA;YAC7C,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC/B,GAAG,CAAC,OAAO,GAAG,MAAM,CAAA;YACpB,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAA;QACzB,CAAC,CAAA;QACD,MAAM,CAAC,OAAO,GAAG,MAAM,CAAA;QACvB,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/dom/createCanvas.d.ts b/build/dom/createCanvas.d.ts new file mode 100644 index 0000000..73ea4d5 --- /dev/null +++ b/build/dom/createCanvas.d.ts @@ -0,0 +1,3 @@ +import { IDimensions } from '../classes/Dimensions'; +export declare function createCanvas({ width, height }: IDimensions): HTMLCanvasElement; +export declare function createCanvasFromMedia(media: HTMLImageElement | HTMLVideoElement | ImageData, dims?: IDimensions): HTMLCanvasElement; diff --git a/build/dom/createCanvas.js b/build/dom/createCanvas.js new file mode 100644 index 0000000..e656020 --- /dev/null +++ b/build/dom/createCanvas.js @@ -0,0 +1,27 @@ +import { env } from '../env'; +import { getContext2dOrThrow } from './getContext2dOrThrow'; +import { getMediaDimensions } from './getMediaDimensions'; +import { isMediaLoaded } from './isMediaLoaded'; +export function createCanvas({ width, height }) { + const { createCanvasElement } = env.getEnv(); + const canvas = createCanvasElement(); + canvas.width = width; + canvas.height = height; + return canvas; +} +export function createCanvasFromMedia(media, dims) { + const { ImageData } = env.getEnv(); + if (!(media instanceof ImageData) && !isMediaLoaded(media)) { + throw new Error('createCanvasFromMedia - media has not finished loading yet'); + } + const { width, height } = dims || getMediaDimensions(media); + const canvas = createCanvas({ width, height }); + if (media instanceof ImageData) { + getContext2dOrThrow(canvas).putImageData(media, 0, 0); + } + else { + getContext2dOrThrow(canvas).drawImage(media, 0, 0, width, height); + } + return canvas; +} +//# sourceMappingURL=createCanvas.js.map \ No newline at end of file diff --git a/build/dom/createCanvas.js.map b/build/dom/createCanvas.js.map new file mode 100644 index 0000000..0feea40 --- /dev/null +++ b/build/dom/createCanvas.js.map @@ -0,0 +1 @@ +{"version":3,"file":"createCanvas.js","sourceRoot":"","sources":["../../src/dom/createCanvas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,UAAU,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,EAAe;IAEzD,MAAM,EAAE,mBAAmB,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;IAC5C,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAA;IACpC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAsD,EAAE,IAAkB;IAE9G,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;IAElC,IAAI,CAAC,CAAC,KAAK,YAAY,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE;QAC1D,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;KAC9E;IAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC3D,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IAE9C,IAAI,KAAK,YAAY,SAAS,EAAE;QAC9B,mBAAmB,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;KACtD;SAAM;QACL,mBAAmB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;KAClE;IACD,OAAO,MAAM,CAAA;AACf,CAAC"} \ No newline at end of file diff --git a/build/dom/extractFaceTensors.d.ts b/build/dom/extractFaceTensors.d.ts new file mode 100644 index 0000000..751da7c --- /dev/null +++ b/build/dom/extractFaceTensors.d.ts @@ -0,0 +1,14 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { Rect } from '../classes'; +import { FaceDetection } from '../classes/FaceDetection'; +/** + * Extracts the tensors of the image regions containing the detected faces. + * Useful if you want to compute the face descriptors for the face images. + * Using this method is faster then extracting a canvas for each face and + * converting them to tensors individually. + * + * @param imageTensor The image tensor that face detection has been performed on. + * @param detections The face detection results or face bounding boxes for that image. + * @returns Tensors of the corresponding image region for each detected face. + */ +export declare function extractFaceTensors(imageTensor: tf.Tensor3D | tf.Tensor4D, detections: Array): Promise; diff --git a/build/dom/extractFaceTensors.js b/build/dom/extractFaceTensors.js new file mode 100644 index 0000000..61e50e5 --- /dev/null +++ b/build/dom/extractFaceTensors.js @@ -0,0 +1,31 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { FaceDetection } from '../classes/FaceDetection'; +import { isTensor3D, isTensor4D } from '../utils'; +/** + * Extracts the tensors of the image regions containing the detected faces. + * Useful if you want to compute the face descriptors for the face images. + * Using this method is faster then extracting a canvas for each face and + * converting them to tensors individually. + * + * @param imageTensor The image tensor that face detection has been performed on. + * @param detections The face detection results or face bounding boxes for that image. + * @returns Tensors of the corresponding image region for each detected face. + */ +export async function extractFaceTensors(imageTensor, detections) { + if (!isTensor3D(imageTensor) && !isTensor4D(imageTensor)) { + throw new Error('extractFaceTensors - expected image tensor to be 3D or 4D'); + } + if (isTensor4D(imageTensor) && imageTensor.shape[0] > 1) { + throw new Error('extractFaceTensors - batchSize > 1 not supported'); + } + return tf.tidy(() => { + const [imgHeight, imgWidth, numChannels] = imageTensor.shape.slice(isTensor4D(imageTensor) ? 1 : 0); + const boxes = detections.map(det => det instanceof FaceDetection + ? det.forSize(imgWidth, imgHeight).box + : det) + .map(box => box.clipAtImageBorders(imgWidth, imgHeight)); + const faceTensors = boxes.map(({ x, y, width, height }) => tf.slice3d(imageTensor.as3D(imgHeight, imgWidth, numChannels), [y, x, 0], [height, width, numChannels])); + return faceTensors; + }); +} +//# sourceMappingURL=extractFaceTensors.js.map \ No newline at end of file diff --git a/build/dom/extractFaceTensors.js.map b/build/dom/extractFaceTensors.js.map new file mode 100644 index 0000000..df8d54d --- /dev/null +++ b/build/dom/extractFaceTensors.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractFaceTensors.js","sourceRoot":"","sources":["../../src/dom/extractFaceTensors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAG5C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAElD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,WAAsC,EACtC,UAAuC;IAGvC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE;QACxD,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAA;KAC7E;IAED,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;QACvD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;KACpE;IAED,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QAClB,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAEnG,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAC1B,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,aAAa;YACjC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,GAAG;YACtC,CAAC,CAAC,GAAG,CACR;aACE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAA;QAE1D,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CACxD,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CACxG,CAAA;QAED,OAAO,WAAW,CAAA;IACpB,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/dom/extractFaces.d.ts b/build/dom/extractFaces.d.ts new file mode 100644 index 0000000..562e7da --- /dev/null +++ b/build/dom/extractFaces.d.ts @@ -0,0 +1,11 @@ +import { FaceDetection } from '../classes/FaceDetection'; +import { Rect } from '../classes/Rect'; +import { TNetInput } from './types'; +/** + * Extracts the image regions containing the detected faces. + * + * @param input The image that face detection has been performed on. + * @param detections The face detection results or face bounding boxes for that image. + * @returns The Canvases of the corresponding image region for each detected face. + */ +export declare function extractFaces(input: TNetInput, detections: Array): Promise; diff --git a/build/dom/extractFaces.js b/build/dom/extractFaces.js new file mode 100644 index 0000000..818fd0a --- /dev/null +++ b/build/dom/extractFaces.js @@ -0,0 +1,39 @@ +import { FaceDetection } from '../classes/FaceDetection'; +import { env } from '../env'; +import { createCanvas } from './createCanvas'; +import { getContext2dOrThrow } from './getContext2dOrThrow'; +import { imageTensorToCanvas } from './imageTensorToCanvas'; +import { toNetInput } from './toNetInput'; +/** + * Extracts the image regions containing the detected faces. + * + * @param input The image that face detection has been performed on. + * @param detections The face detection results or face bounding boxes for that image. + * @returns The Canvases of the corresponding image region for each detected face. + */ +export async function extractFaces(input, detections) { + const { Canvas } = env.getEnv(); + let canvas = input; + if (!(input instanceof Canvas)) { + const netInput = await toNetInput(input); + if (netInput.batchSize > 1) { + throw new Error('extractFaces - batchSize > 1 not supported'); + } + const tensorOrCanvas = netInput.getInput(0); + canvas = tensorOrCanvas instanceof Canvas + ? tensorOrCanvas + : await imageTensorToCanvas(tensorOrCanvas); + } + const ctx = getContext2dOrThrow(canvas); + const boxes = detections.map(det => det instanceof FaceDetection + ? det.forSize(canvas.width, canvas.height).box.floor() + : det) + .map(box => box.clipAtImageBorders(canvas.width, canvas.height)); + return boxes.map(({ x, y, width, height }) => { + const faceImg = createCanvas({ width, height }); + getContext2dOrThrow(faceImg) + .putImageData(ctx.getImageData(x, y, width, height), 0, 0); + return faceImg; + }); +} +//# sourceMappingURL=extractFaces.js.map \ No newline at end of file diff --git a/build/dom/extractFaces.js.map b/build/dom/extractFaces.js.map new file mode 100644 index 0000000..a32ace6 --- /dev/null +++ b/build/dom/extractFaces.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractFaces.js","sourceRoot":"","sources":["../../src/dom/extractFaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAgB,EAChB,UAAuC;IAGvC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;IAE/B,IAAI,MAAM,GAAG,KAA0B,CAAA;IAEvC,IAAI,CAAC,CAAC,KAAK,YAAY,MAAM,CAAC,EAAE;QAC9B,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,CAAA;QAExC,IAAI,QAAQ,CAAC,SAAS,GAAG,CAAC,EAAE;YAC1B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAA;SAC9D;QAED,MAAM,cAAc,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QAC3C,MAAM,GAAG,cAAc,YAAY,MAAM;YACvC,CAAC,CAAC,cAAc;YAChB,CAAC,CAAC,MAAM,mBAAmB,CAAC,cAAc,CAAC,CAAA;KAC9C;IAED,MAAM,GAAG,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAA;IACvC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAC1B,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,aAAa;QACjC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE;QACtD,CAAC,CAAC,GAAG,CACR;SACE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IAElE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;QAC3C,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;QAC/C,mBAAmB,CAAC,OAAO,CAAC;aACzB,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5D,OAAO,OAAO,CAAA;IAChB,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/dom/fetchImage.d.ts b/build/dom/fetchImage.d.ts new file mode 100644 index 0000000..f072b3e --- /dev/null +++ b/build/dom/fetchImage.d.ts @@ -0,0 +1 @@ +export declare function fetchImage(uri: string): Promise; diff --git a/build/dom/fetchImage.js b/build/dom/fetchImage.js new file mode 100644 index 0000000..5caac3a --- /dev/null +++ b/build/dom/fetchImage.js @@ -0,0 +1,11 @@ +import { bufferToImage } from './bufferToImage'; +import { fetchOrThrow } from './fetchOrThrow'; +export async function fetchImage(uri) { + const res = await fetchOrThrow(uri); + const blob = await (res).blob(); + if (!blob.type.startsWith('image/')) { + throw new Error(`fetchImage - expected blob type to be of type image/*, instead have: ${blob.type}, for url: ${res.url}`); + } + return bufferToImage(blob); +} +//# sourceMappingURL=fetchImage.js.map \ No newline at end of file diff --git a/build/dom/fetchImage.js.map b/build/dom/fetchImage.js.map new file mode 100644 index 0000000..d0cc64f --- /dev/null +++ b/build/dom/fetchImage.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fetchImage.js","sourceRoot":"","sources":["../../src/dom/fetchImage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;IACnC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IAE/B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QACnC,MAAM,IAAI,KAAK,CAAC,wEAAwE,IAAI,CAAC,IAAI,cAAc,GAAG,CAAC,GAAG,EAAE,CAAC,CAAA;KAC1H;IACD,OAAO,aAAa,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC"} \ No newline at end of file diff --git a/build/dom/fetchJson.d.ts b/build/dom/fetchJson.d.ts new file mode 100644 index 0000000..bdb5a0b --- /dev/null +++ b/build/dom/fetchJson.d.ts @@ -0,0 +1 @@ +export declare function fetchJson(uri: string): Promise; diff --git a/build/dom/fetchJson.js b/build/dom/fetchJson.js new file mode 100644 index 0000000..215338b --- /dev/null +++ b/build/dom/fetchJson.js @@ -0,0 +1,5 @@ +import { fetchOrThrow } from './fetchOrThrow'; +export async function fetchJson(uri) { + return (await fetchOrThrow(uri)).json(); +} +//# sourceMappingURL=fetchJson.js.map \ No newline at end of file diff --git a/build/dom/fetchJson.js.map b/build/dom/fetchJson.js.map new file mode 100644 index 0000000..6bf9837 --- /dev/null +++ b/build/dom/fetchJson.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fetchJson.js","sourceRoot":"","sources":["../../src/dom/fetchJson.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,GAAW;IAC5C,OAAO,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;AACzC,CAAC"} \ No newline at end of file diff --git a/build/dom/fetchNetWeights.d.ts b/build/dom/fetchNetWeights.d.ts new file mode 100644 index 0000000..f0875fe --- /dev/null +++ b/build/dom/fetchNetWeights.d.ts @@ -0,0 +1 @@ +export declare function fetchNetWeights(uri: string): Promise; diff --git a/build/dom/fetchNetWeights.js b/build/dom/fetchNetWeights.js new file mode 100644 index 0000000..a1bf5ee --- /dev/null +++ b/build/dom/fetchNetWeights.js @@ -0,0 +1,5 @@ +import { fetchOrThrow } from './fetchOrThrow'; +export async function fetchNetWeights(uri) { + return new Float32Array(await (await fetchOrThrow(uri)).arrayBuffer()); +} +//# sourceMappingURL=fetchNetWeights.js.map \ No newline at end of file diff --git a/build/dom/fetchNetWeights.js.map b/build/dom/fetchNetWeights.js.map new file mode 100644 index 0000000..54c9b42 --- /dev/null +++ b/build/dom/fetchNetWeights.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fetchNetWeights.js","sourceRoot":"","sources":["../../src/dom/fetchNetWeights.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAW;IAC/C,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;AACxE,CAAC"} \ No newline at end of file diff --git a/build/dom/fetchOrThrow.d.ts b/build/dom/fetchOrThrow.d.ts new file mode 100644 index 0000000..a73c618 --- /dev/null +++ b/build/dom/fetchOrThrow.d.ts @@ -0,0 +1 @@ +export declare function fetchOrThrow(url: string, init?: RequestInit): Promise; diff --git a/build/dom/fetchOrThrow.js b/build/dom/fetchOrThrow.js new file mode 100644 index 0000000..f00015b --- /dev/null +++ b/build/dom/fetchOrThrow.js @@ -0,0 +1,10 @@ +import { env } from '../env'; +export async function fetchOrThrow(url, init) { + const fetch = env.getEnv().fetch; + const res = await fetch(url, init); + if (!(res.status < 400)) { + throw new Error(`failed to fetch: (${res.status}) ${res.statusText}, from url: ${res.url}`); + } + return res; +} +//# sourceMappingURL=fetchOrThrow.js.map \ No newline at end of file diff --git a/build/dom/fetchOrThrow.js.map b/build/dom/fetchOrThrow.js.map new file mode 100644 index 0000000..555f1d1 --- /dev/null +++ b/build/dom/fetchOrThrow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fetchOrThrow.js","sourceRoot":"","sources":["../../src/dom/fetchOrThrow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAW,EACX,IAAkB;IAGlB,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CAAA;IAChC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,UAAU,eAAe,GAAG,CAAC,GAAG,EAAE,CAAC,CAAA;KAC5F;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"} \ No newline at end of file diff --git a/build/dom/getContext2dOrThrow.d.ts b/build/dom/getContext2dOrThrow.d.ts new file mode 100644 index 0000000..d9dcd4a --- /dev/null +++ b/build/dom/getContext2dOrThrow.d.ts @@ -0,0 +1 @@ +export declare function getContext2dOrThrow(canvasArg: string | HTMLCanvasElement | CanvasRenderingContext2D): CanvasRenderingContext2D; diff --git a/build/dom/getContext2dOrThrow.js b/build/dom/getContext2dOrThrow.js new file mode 100644 index 0000000..c7b04f6 --- /dev/null +++ b/build/dom/getContext2dOrThrow.js @@ -0,0 +1,18 @@ +import { env } from '../env'; +import { resolveInput } from './resolveInput'; +export function getContext2dOrThrow(canvasArg) { + const { Canvas, CanvasRenderingContext2D } = env.getEnv(); + if (canvasArg instanceof CanvasRenderingContext2D) { + return canvasArg; + } + const canvas = resolveInput(canvasArg); + if (!(canvas instanceof Canvas)) { + throw new Error('resolveContext2d - expected canvas to be of instance of Canvas'); + } + const ctx = canvas.getContext('2d'); + if (!ctx) { + throw new Error('resolveContext2d - canvas 2d context is null'); + } + return ctx; +} +//# sourceMappingURL=getContext2dOrThrow.js.map \ No newline at end of file diff --git a/build/dom/getContext2dOrThrow.js.map b/build/dom/getContext2dOrThrow.js.map new file mode 100644 index 0000000..b05eaab --- /dev/null +++ b/build/dom/getContext2dOrThrow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"getContext2dOrThrow.js","sourceRoot":"","sources":["../../src/dom/getContext2dOrThrow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,UAAU,mBAAmB,CAAC,SAAgE;IAElG,MAAM,EAAE,MAAM,EAAE,wBAAwB,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;IAEzD,IAAI,SAAS,YAAY,wBAAwB,EAAE;QACjD,OAAO,SAAS,CAAA;KACjB;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;IAEtC,IAAI,CAAC,CAAC,MAAM,YAAY,MAAM,CAAC,EAAE;QAC/B,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAA;KAClF;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,CAAC,GAAG,EAAE;QACR,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;KAChE;IAED,OAAO,GAAG,CAAA;AACZ,CAAC"} \ No newline at end of file diff --git a/build/dom/getMediaDimensions.d.ts b/build/dom/getMediaDimensions.d.ts new file mode 100644 index 0000000..a946f38 --- /dev/null +++ b/build/dom/getMediaDimensions.d.ts @@ -0,0 +1,2 @@ +import { Dimensions, IDimensions } from '../classes/Dimensions'; +export declare function getMediaDimensions(input: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | IDimensions): Dimensions; diff --git a/build/dom/getMediaDimensions.js b/build/dom/getMediaDimensions.js new file mode 100644 index 0000000..fb8def5 --- /dev/null +++ b/build/dom/getMediaDimensions.js @@ -0,0 +1,13 @@ +import { Dimensions } from '../classes/Dimensions'; +import { env } from '../env'; +export function getMediaDimensions(input) { + const { Image, Video } = env.getEnv(); + if (input instanceof Image) { + return new Dimensions(input.naturalWidth, input.naturalHeight); + } + if (input instanceof Video) { + return new Dimensions(input.videoWidth, input.videoHeight); + } + return new Dimensions(input.width, input.height); +} +//# sourceMappingURL=getMediaDimensions.js.map \ No newline at end of file diff --git a/build/dom/getMediaDimensions.js.map b/build/dom/getMediaDimensions.js.map new file mode 100644 index 0000000..6b87098 --- /dev/null +++ b/build/dom/getMediaDimensions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"getMediaDimensions.js","sourceRoot":"","sources":["../../src/dom/getMediaDimensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAe,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAE7B,MAAM,UAAU,kBAAkB,CAAC,KAA4E;IAE7G,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;IAErC,IAAI,KAAK,YAAY,KAAK,EAAE;QAC1B,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,aAAa,CAAC,CAAA;KAC/D;IACD,IAAI,KAAK,YAAY,KAAK,EAAE;QAC1B,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,WAAW,CAAC,CAAA;KAC3D;IACD,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;AAClD,CAAC"} \ No newline at end of file diff --git a/build/dom/imageTensorToCanvas.d.ts b/build/dom/imageTensorToCanvas.d.ts new file mode 100644 index 0000000..194df68 --- /dev/null +++ b/build/dom/imageTensorToCanvas.d.ts @@ -0,0 +1,2 @@ +import * as tf from '@tensorflow/tfjs-core'; +export declare function imageTensorToCanvas(imgTensor: tf.Tensor, canvas?: HTMLCanvasElement): Promise; diff --git a/build/dom/imageTensorToCanvas.js b/build/dom/imageTensorToCanvas.js new file mode 100644 index 0000000..9725276 --- /dev/null +++ b/build/dom/imageTensorToCanvas.js @@ -0,0 +1,12 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { env } from '../env'; +import { isTensor4D } from '../utils'; +export async function imageTensorToCanvas(imgTensor, canvas) { + const targetCanvas = canvas || env.getEnv().createCanvasElement(); + const [height, width, numChannels] = imgTensor.shape.slice(isTensor4D(imgTensor) ? 1 : 0); + const imgTensor3D = tf.tidy(() => imgTensor.as3D(height, width, numChannels).toInt()); + await tf.browser.toPixels(imgTensor3D, targetCanvas); + imgTensor3D.dispose(); + return targetCanvas; +} +//# sourceMappingURL=imageTensorToCanvas.js.map \ No newline at end of file diff --git a/build/dom/imageTensorToCanvas.js.map b/build/dom/imageTensorToCanvas.js.map new file mode 100644 index 0000000..4628ee2 --- /dev/null +++ b/build/dom/imageTensorToCanvas.js.map @@ -0,0 +1 @@ +{"version":3,"file":"imageTensorToCanvas.js","sourceRoot":"","sources":["../../src/dom/imageTensorToCanvas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAAoB,EACpB,MAA0B;IAG1B,MAAM,YAAY,GAAG,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,mBAAmB,EAAE,CAAA;IAEjE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACzF,MAAM,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;IACrF,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;IAEpD,WAAW,CAAC,OAAO,EAAE,CAAA;IAErB,OAAO,YAAY,CAAA;AACrB,CAAC"} \ No newline at end of file diff --git a/build/dom/imageToSquare.d.ts b/build/dom/imageToSquare.d.ts new file mode 100644 index 0000000..7276c53 --- /dev/null +++ b/build/dom/imageToSquare.d.ts @@ -0,0 +1 @@ +export declare function imageToSquare(input: HTMLImageElement | HTMLCanvasElement, inputSize: number, centerImage?: boolean): HTMLCanvasElement; diff --git a/build/dom/imageToSquare.js b/build/dom/imageToSquare.js new file mode 100644 index 0000000..79cdf2b --- /dev/null +++ b/build/dom/imageToSquare.js @@ -0,0 +1,22 @@ +import { env } from '../env'; +import { createCanvas, createCanvasFromMedia } from './createCanvas'; +import { getContext2dOrThrow } from './getContext2dOrThrow'; +import { getMediaDimensions } from './getMediaDimensions'; +export function imageToSquare(input, inputSize, centerImage = false) { + const { Image, Canvas } = env.getEnv(); + if (!(input instanceof Image || input instanceof Canvas)) { + throw new Error('imageToSquare - expected arg0 to be HTMLImageElement | HTMLCanvasElement'); + } + const dims = getMediaDimensions(input); + const scale = inputSize / Math.max(dims.height, dims.width); + const width = scale * dims.width; + const height = scale * dims.height; + const targetCanvas = createCanvas({ width: inputSize, height: inputSize }); + const inputCanvas = input instanceof Canvas ? input : createCanvasFromMedia(input); + const offset = Math.abs(width - height) / 2; + const dx = centerImage && width < height ? offset : 0; + const dy = centerImage && height < width ? offset : 0; + getContext2dOrThrow(targetCanvas).drawImage(inputCanvas, dx, dy, width, height); + return targetCanvas; +} +//# sourceMappingURL=imageToSquare.js.map \ No newline at end of file diff --git a/build/dom/imageToSquare.js.map b/build/dom/imageToSquare.js.map new file mode 100644 index 0000000..3fe3b95 --- /dev/null +++ b/build/dom/imageToSquare.js.map @@ -0,0 +1 @@ +{"version":3,"file":"imageToSquare.js","sourceRoot":"","sources":["../../src/dom/imageToSquare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,UAAU,aAAa,CAAC,KAA2C,EAAE,SAAiB,EAAE,cAAuB,KAAK;IAExH,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;IAEtC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,YAAY,MAAM,CAAC,EAAE;QACxD,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAA;KAC5F;IAED,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAA;IACtC,MAAM,KAAK,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAC3D,MAAM,KAAK,GAAG,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IAChC,MAAM,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC,MAAM,CAAA;IAElC,MAAM,YAAY,GAAG,YAAY,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;IAC1E,MAAM,WAAW,GAAG,KAAK,YAAY,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAA;IAElF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IAC3C,MAAM,EAAE,GAAG,WAAW,IAAI,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IACrD,MAAM,EAAE,GAAG,WAAW,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IACrD,mBAAmB,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;IAE/E,OAAO,YAAY,CAAA;AACrB,CAAC"} \ No newline at end of file diff --git a/build/dom/index.d.ts b/build/dom/index.d.ts new file mode 100644 index 0000000..10e5aff --- /dev/null +++ b/build/dom/index.d.ts @@ -0,0 +1,21 @@ +export * from './awaitMediaLoaded'; +export * from './bufferToImage'; +export * from './createCanvas'; +export * from './extractFaces'; +export * from './extractFaceTensors'; +export * from './fetchImage'; +export * from './fetchJson'; +export * from './fetchNetWeights'; +export * from './fetchOrThrow'; +export * from './getContext2dOrThrow'; +export * from './getMediaDimensions'; +export * from './imageTensorToCanvas'; +export * from './imageToSquare'; +export * from './isMediaElement'; +export * from './isMediaLoaded'; +export * from './loadWeightMap'; +export * from './matchDimensions'; +export * from './NetInput'; +export * from './resolveInput'; +export * from './toNetInput'; +export * from './types'; diff --git a/build/dom/index.js b/build/dom/index.js new file mode 100644 index 0000000..4ba64a7 --- /dev/null +++ b/build/dom/index.js @@ -0,0 +1,22 @@ +export * from './awaitMediaLoaded'; +export * from './bufferToImage'; +export * from './createCanvas'; +export * from './extractFaces'; +export * from './extractFaceTensors'; +export * from './fetchImage'; +export * from './fetchJson'; +export * from './fetchNetWeights'; +export * from './fetchOrThrow'; +export * from './getContext2dOrThrow'; +export * from './getMediaDimensions'; +export * from './imageTensorToCanvas'; +export * from './imageToSquare'; +export * from './isMediaElement'; +export * from './isMediaLoaded'; +export * from './loadWeightMap'; +export * from './matchDimensions'; +export * from './NetInput'; +export * from './resolveInput'; +export * from './toNetInput'; +export * from './types'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/dom/index.js.map b/build/dom/index.js.map new file mode 100644 index 0000000..8e7927e --- /dev/null +++ b/build/dom/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dom/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,sBAAsB,CAAA;AACpC,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,uBAAuB,CAAA;AACrC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA;AACjC,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA"} \ No newline at end of file diff --git a/build/dom/isMediaElement.d.ts b/build/dom/isMediaElement.d.ts new file mode 100644 index 0000000..1d359c2 --- /dev/null +++ b/build/dom/isMediaElement.d.ts @@ -0,0 +1 @@ +export declare function isMediaElement(input: any): boolean; diff --git a/build/dom/isMediaElement.js b/build/dom/isMediaElement.js new file mode 100644 index 0000000..f0305c0 --- /dev/null +++ b/build/dom/isMediaElement.js @@ -0,0 +1,8 @@ +import { env } from '../env'; +export function isMediaElement(input) { + const { Image, Canvas, Video } = env.getEnv(); + return input instanceof Image + || input instanceof Canvas + || input instanceof Video; +} +//# sourceMappingURL=isMediaElement.js.map \ No newline at end of file diff --git a/build/dom/isMediaElement.js.map b/build/dom/isMediaElement.js.map new file mode 100644 index 0000000..47c5138 --- /dev/null +++ b/build/dom/isMediaElement.js.map @@ -0,0 +1 @@ +{"version":3,"file":"isMediaElement.js","sourceRoot":"","sources":["../../src/dom/isMediaElement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAE7B,MAAM,UAAU,cAAc,CAAC,KAAU;IAEvC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;IAE7C,OAAO,KAAK,YAAY,KAAK;WACxB,KAAK,YAAY,MAAM;WACvB,KAAK,YAAY,KAAK,CAAA;AAC7B,CAAC"} \ No newline at end of file diff --git a/build/dom/isMediaLoaded.d.ts b/build/dom/isMediaLoaded.d.ts new file mode 100644 index 0000000..211e01e --- /dev/null +++ b/build/dom/isMediaLoaded.d.ts @@ -0,0 +1 @@ +export declare function isMediaLoaded(media: HTMLImageElement | HTMLVideoElement): boolean; diff --git a/build/dom/isMediaLoaded.js b/build/dom/isMediaLoaded.js new file mode 100644 index 0000000..266a8e9 --- /dev/null +++ b/build/dom/isMediaLoaded.js @@ -0,0 +1,7 @@ +import { env } from '../env'; +export function isMediaLoaded(media) { + const { Image, Video } = env.getEnv(); + return (media instanceof Image && media.complete) + || (media instanceof Video && media.readyState >= 3); +} +//# sourceMappingURL=isMediaLoaded.js.map \ No newline at end of file diff --git a/build/dom/isMediaLoaded.js.map b/build/dom/isMediaLoaded.js.map new file mode 100644 index 0000000..1efee53 --- /dev/null +++ b/build/dom/isMediaLoaded.js.map @@ -0,0 +1 @@ +{"version":3,"file":"isMediaLoaded.js","sourceRoot":"","sources":["../../src/dom/isMediaLoaded.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAE7B,MAAM,UAAU,aAAa,CAAC,KAA0C;IAEtE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;IAErC,OAAO,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC;WAC5C,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC,CAAA;AACxD,CAAC"} \ No newline at end of file diff --git a/build/dom/loadWeightMap.d.ts b/build/dom/loadWeightMap.d.ts new file mode 100644 index 0000000..942ed6a --- /dev/null +++ b/build/dom/loadWeightMap.d.ts @@ -0,0 +1,2 @@ +import * as tf from '@tensorflow/tfjs-core'; +export declare function loadWeightMap(uri: string | undefined, defaultModelName: string): Promise; diff --git a/build/dom/loadWeightMap.js b/build/dom/loadWeightMap.js new file mode 100644 index 0000000..4791577 --- /dev/null +++ b/build/dom/loadWeightMap.js @@ -0,0 +1,9 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { getModelUris } from '../common/getModelUris'; +import { fetchJson } from './fetchJson'; +export async function loadWeightMap(uri, defaultModelName) { + const { manifestUri, modelBaseUri } = getModelUris(uri, defaultModelName); + const manifest = await fetchJson(manifestUri); + return tf.io.loadWeights(manifest, modelBaseUri); +} +//# sourceMappingURL=loadWeightMap.js.map \ No newline at end of file diff --git a/build/dom/loadWeightMap.js.map b/build/dom/loadWeightMap.js.map new file mode 100644 index 0000000..1ab9647 --- /dev/null +++ b/build/dom/loadWeightMap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"loadWeightMap.js","sourceRoot":"","sources":["../../src/dom/loadWeightMap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAuB,EACvB,gBAAwB;IAExB,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAA;IAEzE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAA8B,WAAW,CAAC,CAAA;IAE1E,OAAO,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;AAClD,CAAC"} \ No newline at end of file diff --git a/build/dom/matchDimensions.d.ts b/build/dom/matchDimensions.d.ts new file mode 100644 index 0000000..9fab19a --- /dev/null +++ b/build/dom/matchDimensions.d.ts @@ -0,0 +1,5 @@ +import { IDimensions } from '../classes'; +export declare function matchDimensions(input: IDimensions, reference: IDimensions, useMediaDimensions?: boolean): { + width: number; + height: number; +}; diff --git a/build/dom/matchDimensions.js b/build/dom/matchDimensions.js new file mode 100644 index 0000000..aa32108 --- /dev/null +++ b/build/dom/matchDimensions.js @@ -0,0 +1,10 @@ +import { getMediaDimensions } from './getMediaDimensions'; +export function matchDimensions(input, reference, useMediaDimensions = false) { + const { width, height } = useMediaDimensions + ? getMediaDimensions(reference) + : reference; + input.width = width; + input.height = height; + return { width, height }; +} +//# sourceMappingURL=matchDimensions.js.map \ No newline at end of file diff --git a/build/dom/matchDimensions.js.map b/build/dom/matchDimensions.js.map new file mode 100644 index 0000000..5ffc284 --- /dev/null +++ b/build/dom/matchDimensions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"matchDimensions.js","sourceRoot":"","sources":["../../src/dom/matchDimensions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,UAAU,eAAe,CAAC,KAAkB,EAAE,SAAsB,EAAE,qBAA8B,KAAK;IAC7G,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,kBAAkB;QAC1C,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC;QAC/B,CAAC,CAAC,SAAS,CAAA;IACb,KAAK,CAAC,KAAK,GAAG,KAAK,CAAA;IACnB,KAAK,CAAC,MAAM,GAAG,MAAM,CAAA;IACrB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;AAC1B,CAAC"} \ No newline at end of file diff --git a/build/dom/resolveInput.d.ts b/build/dom/resolveInput.d.ts new file mode 100644 index 0000000..2fa6a8a --- /dev/null +++ b/build/dom/resolveInput.d.ts @@ -0,0 +1 @@ +export declare function resolveInput(arg: string | any): any; diff --git a/build/dom/resolveInput.js b/build/dom/resolveInput.js new file mode 100644 index 0000000..37b844d --- /dev/null +++ b/build/dom/resolveInput.js @@ -0,0 +1,8 @@ +import { env } from '../env'; +export function resolveInput(arg) { + if (!env.isNodejs() && typeof arg === 'string') { + return document.getElementById(arg); + } + return arg; +} +//# sourceMappingURL=resolveInput.js.map \ No newline at end of file diff --git a/build/dom/resolveInput.js.map b/build/dom/resolveInput.js.map new file mode 100644 index 0000000..2638891 --- /dev/null +++ b/build/dom/resolveInput.js.map @@ -0,0 +1 @@ +{"version":3,"file":"resolveInput.js","sourceRoot":"","sources":["../../src/dom/resolveInput.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAE7B,MAAM,UAAU,YAAY,CAAC,GAAiB;IAC5C,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;QAC9C,OAAO,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;KACpC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"} \ No newline at end of file diff --git a/build/dom/toNetInput.d.ts b/build/dom/toNetInput.d.ts new file mode 100644 index 0000000..b361487 --- /dev/null +++ b/build/dom/toNetInput.d.ts @@ -0,0 +1,10 @@ +import { NetInput } from './NetInput'; +import { TNetInput } from './types'; +/** + * Validates the input to make sure, they are valid net inputs and awaits all media elements + * to be finished loading. + * + * @param input The input, which can be a media element or an array of different media elements. + * @returns A NetInput instance, which can be passed into one of the neural networks. + */ +export declare function toNetInput(inputs: TNetInput): Promise; diff --git a/build/dom/toNetInput.js b/build/dom/toNetInput.js new file mode 100644 index 0000000..e96792b --- /dev/null +++ b/build/dom/toNetInput.js @@ -0,0 +1,44 @@ +import { isTensor3D, isTensor4D } from '../utils'; +import { awaitMediaLoaded } from './awaitMediaLoaded'; +import { isMediaElement } from './isMediaElement'; +import { NetInput } from './NetInput'; +import { resolveInput } from './resolveInput'; +/** + * Validates the input to make sure, they are valid net inputs and awaits all media elements + * to be finished loading. + * + * @param input The input, which can be a media element or an array of different media elements. + * @returns A NetInput instance, which can be passed into one of the neural networks. + */ +export async function toNetInput(inputs) { + if (inputs instanceof NetInput) { + return inputs; + } + let inputArgArray = Array.isArray(inputs) + ? inputs + : [inputs]; + if (!inputArgArray.length) { + throw new Error('toNetInput - empty array passed as input'); + } + const getIdxHint = (idx) => Array.isArray(inputs) ? ` at input index ${idx}:` : ''; + const inputArray = inputArgArray.map(resolveInput); + inputArray.forEach((input, i) => { + if (!isMediaElement(input) && !isTensor3D(input) && !isTensor4D(input)) { + if (typeof inputArgArray[i] === 'string') { + throw new Error(`toNetInput -${getIdxHint(i)} string passed, but could not resolve HTMLElement for element id ${inputArgArray[i]}`); + } + throw new Error(`toNetInput -${getIdxHint(i)} expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id`); + } + if (isTensor4D(input)) { + // if tf.Tensor4D is passed in the input array, the batch size has to be 1 + const batchSize = input.shape[0]; + if (batchSize !== 1) { + throw new Error(`toNetInput -${getIdxHint(i)} tf.Tensor4D with batchSize ${batchSize} passed, but not supported in input array`); + } + } + }); + // wait for all media elements being loaded + await Promise.all(inputArray.map(input => isMediaElement(input) && awaitMediaLoaded(input))); + return new NetInput(inputArray, Array.isArray(inputs)); +} +//# sourceMappingURL=toNetInput.js.map \ No newline at end of file diff --git a/build/dom/toNetInput.js.map b/build/dom/toNetInput.js.map new file mode 100644 index 0000000..9de0b21 --- /dev/null +++ b/build/dom/toNetInput.js.map @@ -0,0 +1 @@ +{"version":3,"file":"toNetInput.js","sourceRoot":"","sources":["../../src/dom/toNetInput.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAiB;IAChD,IAAI,MAAM,YAAY,QAAQ,EAAE;QAC9B,OAAO,MAAM,CAAA;KACd;IAED,IAAI,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QACrC,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;IAEd,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;QACzB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;KAC5D;IAED,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,mBAAmB,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IAE1F,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;IAElD,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC9B,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;YAEtE,IAAI,OAAO,aAAa,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;gBACxC,MAAM,IAAI,KAAK,CAAC,eAAe,UAAU,CAAC,CAAC,CAAC,oEAAoE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;aACpI;YAED,MAAM,IAAI,KAAK,CAAC,eAAe,UAAU,CAAC,CAAC,CAAC,6HAA6H,CAAC,CAAA;SAC3K;QAED,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE;YACrB,0EAA0E;YAC1E,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAChC,IAAI,SAAS,KAAK,CAAC,EAAE;gBACnB,MAAM,IAAI,KAAK,CAAC,eAAe,UAAU,CAAC,CAAC,CAAC,+BAA+B,SAAS,2CAA2C,CAAC,CAAA;aACjI;SACF;IACH,CAAC,CAAC,CAAA;IAEF,2CAA2C;IAC3C,MAAM,OAAO,CAAC,GAAG,CACf,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAC1E,CAAA;IAED,OAAO,IAAI,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;AACxD,CAAC"} \ No newline at end of file diff --git a/build/dom/types.d.ts b/build/dom/types.d.ts new file mode 100644 index 0000000..fac87b2 --- /dev/null +++ b/build/dom/types.d.ts @@ -0,0 +1,6 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { NetInput } from './NetInput'; +export declare type TMediaElement = HTMLImageElement | HTMLVideoElement | HTMLCanvasElement; +export declare type TResolvedNetInput = TMediaElement | tf.Tensor3D | tf.Tensor4D; +export declare type TNetInputArg = string | TResolvedNetInput; +export declare type TNetInput = TNetInputArg | Array | NetInput | tf.Tensor4D; diff --git a/build/dom/types.js b/build/dom/types.js new file mode 100644 index 0000000..5b2306a --- /dev/null +++ b/build/dom/types.js @@ -0,0 +1 @@ +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/build/dom/types.js.map b/build/dom/types.js.map new file mode 100644 index 0000000..3c42080 --- /dev/null +++ b/build/dom/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/dom/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/draw/DrawBox.d.ts b/build/draw/DrawBox.d.ts new file mode 100644 index 0000000..6fd97be --- /dev/null +++ b/build/draw/DrawBox.d.ts @@ -0,0 +1,21 @@ +import { Box, IBoundingBox, IRect } from '../classes'; +import { DrawTextFieldOptions, IDrawTextFieldOptions } from './DrawTextField'; +export interface IDrawBoxOptions { + boxColor?: string; + lineWidth?: number; + drawLabelOptions?: IDrawTextFieldOptions; + label?: string; +} +export declare class DrawBoxOptions { + boxColor: string; + lineWidth: number; + drawLabelOptions: DrawTextFieldOptions; + label?: string; + constructor(options?: IDrawBoxOptions); +} +export declare class DrawBox { + box: Box; + options: DrawBoxOptions; + constructor(box: IBoundingBox | IRect, options?: IDrawBoxOptions); + draw(canvasArg: string | HTMLCanvasElement | CanvasRenderingContext2D): void; +} diff --git a/build/draw/DrawBox.js b/build/draw/DrawBox.js new file mode 100644 index 0000000..ca6f256 --- /dev/null +++ b/build/draw/DrawBox.js @@ -0,0 +1,35 @@ +import { Box } from '../classes'; +import { getContext2dOrThrow } from '../dom/getContext2dOrThrow'; +import { AnchorPosition, DrawTextField, DrawTextFieldOptions } from './DrawTextField'; +export class DrawBoxOptions { + constructor(options = {}) { + const { boxColor, lineWidth, label, drawLabelOptions } = options; + this.boxColor = boxColor || 'rgba(0, 0, 255, 1)'; + this.lineWidth = lineWidth || 2; + this.label = label; + const defaultDrawLabelOptions = { + anchorPosition: AnchorPosition.BOTTOM_LEFT, + backgroundColor: this.boxColor + }; + this.drawLabelOptions = new DrawTextFieldOptions(Object.assign({}, defaultDrawLabelOptions, drawLabelOptions)); + } +} +export class DrawBox { + constructor(box, options = {}) { + this.box = new Box(box); + this.options = new DrawBoxOptions(options); + } + draw(canvasArg) { + const ctx = getContext2dOrThrow(canvasArg); + const { boxColor, lineWidth } = this.options; + const { x, y, width, height } = this.box; + ctx.strokeStyle = boxColor; + ctx.lineWidth = lineWidth; + ctx.strokeRect(x, y, width, height); + const { label } = this.options; + if (label) { + new DrawTextField([label], { x: x - (lineWidth / 2), y }, this.options.drawLabelOptions).draw(canvasArg); + } + } +} +//# sourceMappingURL=DrawBox.js.map \ No newline at end of file diff --git a/build/draw/DrawBox.js.map b/build/draw/DrawBox.js.map new file mode 100644 index 0000000..5156f6b --- /dev/null +++ b/build/draw/DrawBox.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DrawBox.js","sourceRoot":"","sources":["../../src/draw/DrawBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAuB,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAyB,MAAM,iBAAiB,CAAC;AAS7G,MAAM,OAAO,cAAc;IAMzB,YAAY,UAA2B,EAAE;QACvC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAA;QAChE,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,oBAAoB,CAAA;QAChD,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,CAAC,CAAA;QAC/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAElB,MAAM,uBAAuB,GAAG;YAC9B,cAAc,EAAE,cAAc,CAAC,WAAW;YAC1C,eAAe,EAAE,IAAI,CAAC,QAAQ;SAC/B,CAAA;QACD,IAAI,CAAC,gBAAgB,GAAG,IAAI,oBAAoB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,uBAAuB,EAAE,gBAAgB,CAAC,CAAC,CAAA;IAChH,CAAC;CACF;AAED,MAAM,OAAO,OAAO;IAIlB,YACE,GAAyB,EACzB,UAA2B,EAAE;QAE7B,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QACvB,IAAI,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,CAAA;IAC5C,CAAC;IAED,IAAI,CAAC,SAAgE;QACnE,MAAM,GAAG,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAA;QAE1C,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAE5C,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAA;QACxC,GAAG,CAAC,WAAW,GAAG,QAAQ,CAAA;QAC1B,GAAG,CAAC,SAAS,GAAG,SAAS,CAAA;QACzB,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAEnC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAC9B,IAAI,KAAK,EAAE;YACT,IAAI,aAAa,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;SACzG;IACH,CAAC;CACF"} \ No newline at end of file diff --git a/build/draw/DrawFaceLandmarks.d.ts b/build/draw/DrawFaceLandmarks.d.ts new file mode 100644 index 0000000..4833c4b --- /dev/null +++ b/build/draw/DrawFaceLandmarks.d.ts @@ -0,0 +1,28 @@ +import { FaceLandmarks } from '../classes/FaceLandmarks'; +import { WithFaceDetection } from '../factories/WithFaceDetection'; +import { WithFaceLandmarks } from '../factories/WithFaceLandmarks'; +export interface IDrawFaceLandmarksOptions { + drawLines?: boolean; + drawPoints?: boolean; + lineWidth?: number; + pointSize?: number; + lineColor?: string; + pointColor?: string; +} +export declare class DrawFaceLandmarksOptions { + drawLines: boolean; + drawPoints: boolean; + lineWidth: number; + pointSize: number; + lineColor: string; + pointColor: string; + constructor(options?: IDrawFaceLandmarksOptions); +} +export declare class DrawFaceLandmarks { + faceLandmarks: FaceLandmarks; + options: DrawFaceLandmarksOptions; + constructor(faceLandmarks: FaceLandmarks, options?: IDrawFaceLandmarksOptions); + draw(canvasArg: string | HTMLCanvasElement | CanvasRenderingContext2D): void; +} +export declare type DrawFaceLandmarksInput = FaceLandmarks | WithFaceLandmarks>; +export declare function drawFaceLandmarks(canvasArg: string | HTMLCanvasElement, faceLandmarks: DrawFaceLandmarksInput | Array): void; diff --git a/build/draw/DrawFaceLandmarks.js b/build/draw/DrawFaceLandmarks.js new file mode 100644 index 0000000..9aa0e35 --- /dev/null +++ b/build/draw/DrawFaceLandmarks.js @@ -0,0 +1,60 @@ +import { FaceLandmarks } from '../classes/FaceLandmarks'; +import { FaceLandmarks68 } from '../classes/FaceLandmarks68'; +import { getContext2dOrThrow } from '../dom/getContext2dOrThrow'; +import { isWithFaceLandmarks } from '../factories/WithFaceLandmarks'; +import { drawContour } from './drawContour'; +export class DrawFaceLandmarksOptions { + constructor(options = {}) { + const { drawLines = true, drawPoints = true, lineWidth, lineColor, pointSize, pointColor } = options; + this.drawLines = drawLines; + this.drawPoints = drawPoints; + this.lineWidth = lineWidth || 1; + this.pointSize = pointSize || 2; + this.lineColor = lineColor || 'rgba(0, 255, 255, 1)'; + this.pointColor = pointColor || 'rgba(255, 0, 255, 1)'; + } +} +export class DrawFaceLandmarks { + constructor(faceLandmarks, options = {}) { + this.faceLandmarks = faceLandmarks; + this.options = new DrawFaceLandmarksOptions(options); + } + draw(canvasArg) { + const ctx = getContext2dOrThrow(canvasArg); + const { drawLines, drawPoints, lineWidth, lineColor, pointSize, pointColor } = this.options; + if (drawLines && this.faceLandmarks instanceof FaceLandmarks68) { + ctx.strokeStyle = lineColor; + ctx.lineWidth = lineWidth; + drawContour(ctx, this.faceLandmarks.getJawOutline()); + drawContour(ctx, this.faceLandmarks.getLeftEyeBrow()); + drawContour(ctx, this.faceLandmarks.getRightEyeBrow()); + drawContour(ctx, this.faceLandmarks.getNose()); + drawContour(ctx, this.faceLandmarks.getLeftEye(), true); + drawContour(ctx, this.faceLandmarks.getRightEye(), true); + drawContour(ctx, this.faceLandmarks.getMouth(), true); + } + if (drawPoints) { + ctx.strokeStyle = pointColor; + ctx.fillStyle = pointColor; + const drawPoint = (pt) => { + ctx.beginPath(); + ctx.arc(pt.x, pt.y, pointSize, 0, 2 * Math.PI); + ctx.fill(); + }; + this.faceLandmarks.positions.forEach(drawPoint); + } + } +} +export function drawFaceLandmarks(canvasArg, faceLandmarks) { + const faceLandmarksArray = Array.isArray(faceLandmarks) ? faceLandmarks : [faceLandmarks]; + faceLandmarksArray.forEach(f => { + const landmarks = f instanceof FaceLandmarks + ? f + : (isWithFaceLandmarks(f) ? f.landmarks : undefined); + if (!landmarks) { + throw new Error('drawFaceLandmarks - expected faceExpressions to be FaceLandmarks | WithFaceLandmarks> or array thereof'); + } + new DrawFaceLandmarks(landmarks).draw(canvasArg); + }); +} +//# sourceMappingURL=DrawFaceLandmarks.js.map \ No newline at end of file diff --git a/build/draw/DrawFaceLandmarks.js.map b/build/draw/DrawFaceLandmarks.js.map new file mode 100644 index 0000000..50f2ac5 --- /dev/null +++ b/build/draw/DrawFaceLandmarks.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DrawFaceLandmarks.js","sourceRoot":"","sources":["../../src/draw/DrawFaceLandmarks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,OAAO,EAAE,mBAAmB,EAAqB,MAAM,gCAAgC,CAAC;AACxF,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAW5C,MAAM,OAAO,wBAAwB;IAQnC,YAAY,UAAqC,EAAE;QACjD,MAAM,EAAE,SAAS,GAAG,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAA;QACpG,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,CAAC,CAAA;QAC/B,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,CAAC,CAAA;QAC/B,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,sBAAsB,CAAA;QACpD,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,sBAAsB,CAAA;IACxD,CAAC;CACF;AAED,MAAM,OAAO,iBAAiB;IAI5B,YACE,aAA4B,EAC5B,UAAqC,EAAE;QAEvC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;QAClC,IAAI,CAAC,OAAO,GAAG,IAAI,wBAAwB,CAAC,OAAO,CAAC,CAAA;IACtD,CAAC;IAED,IAAI,CAAC,SAAgE;QACnE,MAAM,GAAG,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAA;QAE1C,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAE3F,IAAI,SAAS,IAAI,IAAI,CAAC,aAAa,YAAY,eAAe,EAAE;YAC9D,GAAG,CAAC,WAAW,GAAG,SAAS,CAAA;YAC3B,GAAG,CAAC,SAAS,GAAG,SAAS,CAAA;YACzB,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC,CAAA;YACpD,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE,CAAC,CAAA;YACrD,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC,CAAA;YACtD,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAA;YAC9C,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,CAAA;YACvD,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,CAAA;YACxD,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAA;SACtD;QAED,IAAI,UAAU,EAAE;YACd,GAAG,CAAC,WAAW,GAAG,UAAU,CAAA;YAC5B,GAAG,CAAC,SAAS,GAAG,UAAU,CAAA;YAE1B,MAAM,SAAS,GAAG,CAAC,EAAU,EAAE,EAAE;gBAC/B,GAAG,CAAC,SAAS,EAAE,CAAA;gBACf,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAA;gBAC9C,GAAG,CAAC,IAAI,EAAE,CAAA;YACZ,CAAC,CAAA;YACD,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;SAChD;IACH,CAAC;CACF;AAID,MAAM,UAAU,iBAAiB,CAC/B,SAAqC,EACrC,aAAqE;IAErE,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAA;IACzF,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QAC7B,MAAM,SAAS,GAAG,CAAC,YAAY,aAAa;YAC1C,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,SAAS,EAAE;YACd,MAAM,IAAI,KAAK,CAAC,8HAA8H,CAAC,CAAA;SAChJ;QAED,IAAI,iBAAiB,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/draw/DrawTextField.d.ts b/build/draw/DrawTextField.d.ts new file mode 100644 index 0000000..abed043 --- /dev/null +++ b/build/draw/DrawTextField.d.ts @@ -0,0 +1,34 @@ +import { IDimensions, IPoint } from '../classes'; +export declare enum AnchorPosition { + TOP_LEFT = "TOP_LEFT", + TOP_RIGHT = "TOP_RIGHT", + BOTTOM_LEFT = "BOTTOM_LEFT", + BOTTOM_RIGHT = "BOTTOM_RIGHT" +} +export interface IDrawTextFieldOptions { + anchorPosition?: AnchorPosition; + backgroundColor?: string; + fontColor?: string; + fontSize?: number; + fontStyle?: string; + padding?: number; +} +export declare class DrawTextFieldOptions implements IDrawTextFieldOptions { + anchorPosition: AnchorPosition; + backgroundColor: string; + fontColor: string; + fontSize: number; + fontStyle: string; + padding: number; + constructor(options?: IDrawTextFieldOptions); +} +export declare class DrawTextField { + text: string[]; + anchor: IPoint; + options: DrawTextFieldOptions; + constructor(text: string | string[] | DrawTextField, anchor: IPoint, options?: IDrawTextFieldOptions); + measureWidth(ctx: CanvasRenderingContext2D): number; + measureHeight(): number; + getUpperLeft(ctx: CanvasRenderingContext2D, canvasDims?: IDimensions): IPoint; + draw(canvasArg: string | HTMLCanvasElement | CanvasRenderingContext2D): void; +} diff --git a/build/draw/DrawTextField.js b/build/draw/DrawTextField.js new file mode 100644 index 0000000..8e6024b --- /dev/null +++ b/build/draw/DrawTextField.js @@ -0,0 +1,72 @@ +import { getContext2dOrThrow } from '../dom/getContext2dOrThrow'; +import { resolveInput } from '../dom/resolveInput'; +export var AnchorPosition; +(function (AnchorPosition) { + AnchorPosition["TOP_LEFT"] = "TOP_LEFT"; + AnchorPosition["TOP_RIGHT"] = "TOP_RIGHT"; + AnchorPosition["BOTTOM_LEFT"] = "BOTTOM_LEFT"; + AnchorPosition["BOTTOM_RIGHT"] = "BOTTOM_RIGHT"; +})(AnchorPosition || (AnchorPosition = {})); +export class DrawTextFieldOptions { + constructor(options = {}) { + const { anchorPosition, backgroundColor, fontColor, fontSize, fontStyle, padding } = options; + this.anchorPosition = anchorPosition || AnchorPosition.TOP_LEFT; + this.backgroundColor = backgroundColor || 'rgba(0, 0, 0, 0.5)'; + this.fontColor = fontColor || 'rgba(255, 255, 255, 1)'; + this.fontSize = fontSize || 14; + this.fontStyle = fontStyle || 'Georgia'; + this.padding = padding || 4; + } +} +export class DrawTextField { + constructor(text, anchor, options = {}) { + this.text = typeof text === 'string' + ? [text] + : (text instanceof DrawTextField ? text.text : text); + this.anchor = anchor; + this.options = new DrawTextFieldOptions(options); + } + measureWidth(ctx) { + const { padding } = this.options; + return this.text.map(l => ctx.measureText(l).width).reduce((w0, w1) => w0 < w1 ? w1 : w0, 0) + (2 * padding); + } + measureHeight() { + const { fontSize, padding } = this.options; + return this.text.length * fontSize + (2 * padding); + } + getUpperLeft(ctx, canvasDims) { + const { anchorPosition } = this.options; + const isShiftLeft = anchorPosition === AnchorPosition.BOTTOM_RIGHT || anchorPosition === AnchorPosition.TOP_RIGHT; + const isShiftTop = anchorPosition === AnchorPosition.BOTTOM_LEFT || anchorPosition === AnchorPosition.BOTTOM_RIGHT; + const textFieldWidth = this.measureWidth(ctx); + const textFieldHeight = this.measureHeight(); + const x = (isShiftLeft ? this.anchor.x - textFieldWidth : this.anchor.x); + const y = isShiftTop ? this.anchor.y - textFieldHeight : this.anchor.y; + // adjust anchor if text box exceeds canvas borders + if (canvasDims) { + const { width, height } = canvasDims; + const newX = Math.max(Math.min(x, width - textFieldWidth), 0); + const newY = Math.max(Math.min(y, height - textFieldHeight), 0); + return { x: newX, y: newY }; + } + return { x, y }; + } + draw(canvasArg) { + const canvas = resolveInput(canvasArg); + const ctx = getContext2dOrThrow(canvas); + const { backgroundColor, fontColor, fontSize, fontStyle, padding } = this.options; + ctx.font = `${fontSize}px ${fontStyle}`; + const maxTextWidth = this.measureWidth(ctx); + const textHeight = this.measureHeight(); + ctx.fillStyle = backgroundColor; + const upperLeft = this.getUpperLeft(ctx, canvas); + ctx.fillRect(upperLeft.x, upperLeft.y, maxTextWidth, textHeight); + ctx.fillStyle = fontColor; + this.text.forEach((textLine, i) => { + const x = padding + upperLeft.x; + const y = padding + upperLeft.y + ((i + 1) * fontSize); + ctx.fillText(textLine, x, y); + }); + } +} +//# sourceMappingURL=DrawTextField.js.map \ No newline at end of file diff --git a/build/draw/DrawTextField.js.map b/build/draw/DrawTextField.js.map new file mode 100644 index 0000000..d76c823 --- /dev/null +++ b/build/draw/DrawTextField.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DrawTextField.js","sourceRoot":"","sources":["../../src/draw/DrawTextField.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/draw/drawContour.d.ts b/build/draw/drawContour.d.ts new file mode 100644 index 0000000..209c87d --- /dev/null +++ b/build/draw/drawContour.d.ts @@ -0,0 +1,2 @@ +import { Point } from '../classes'; +export declare function drawContour(ctx: CanvasRenderingContext2D, points: Point[], isClosed?: boolean): void; diff --git a/build/draw/drawContour.js b/build/draw/drawContour.js new file mode 100644 index 0000000..2278a13 --- /dev/null +++ b/build/draw/drawContour.js @@ -0,0 +1,19 @@ +export function drawContour(ctx, points, isClosed = false) { + ctx.beginPath(); + points.slice(1).forEach(({ x, y }, prevIdx) => { + const from = points[prevIdx]; + ctx.moveTo(from.x, from.y); + ctx.lineTo(x, y); + }); + if (isClosed) { + const from = points[points.length - 1]; + const to = points[0]; + if (!from || !to) { + return; + } + ctx.moveTo(from.x, from.y); + ctx.lineTo(to.x, to.y); + } + ctx.stroke(); +} +//# sourceMappingURL=drawContour.js.map \ No newline at end of file diff --git a/build/draw/drawContour.js.map b/build/draw/drawContour.js.map new file mode 100644 index 0000000..8013d7c --- /dev/null +++ b/build/draw/drawContour.js.map @@ -0,0 +1 @@ +{"version":3,"file":"drawContour.js","sourceRoot":"","sources":["../../src/draw/drawContour.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CACzB,GAA6B,EAC7B,MAAe,EACf,WAAoB,KAAK;IAEzB,GAAG,CAAC,SAAS,EAAE,CAAA;IAEf,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE;QAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;QAC5B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;QAC1B,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAClB,CAAC,CAAC,CAAA;IAEF,IAAI,QAAQ,EAAE;QACZ,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACtC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QACpB,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE;YAChB,OAAM;SACP;QAED,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;QAC1B,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;KACvB;IAED,GAAG,CAAC,MAAM,EAAE,CAAA;AACd,CAAC"} \ No newline at end of file diff --git a/build/draw/drawDetections.d.ts b/build/draw/drawDetections.d.ts new file mode 100644 index 0000000..9e94d7e --- /dev/null +++ b/build/draw/drawDetections.d.ts @@ -0,0 +1,5 @@ +import { IBoundingBox, IRect } from '../classes'; +import { FaceDetection } from '../classes/FaceDetection'; +import { WithFaceDetection } from '../factories/WithFaceDetection'; +export declare type TDrawDetectionsInput = IRect | IBoundingBox | FaceDetection | WithFaceDetection<{}>; +export declare function drawDetections(canvasArg: string | HTMLCanvasElement, detections: TDrawDetectionsInput | Array): void; diff --git a/build/draw/drawDetections.js b/build/draw/drawDetections.js new file mode 100644 index 0000000..d56ab27 --- /dev/null +++ b/build/draw/drawDetections.js @@ -0,0 +1,19 @@ +import { Box } from '../classes'; +import { FaceDetection } from '../classes/FaceDetection'; +import { isWithFaceDetection } from '../factories/WithFaceDetection'; +import { round } from '../utils'; +import { DrawBox } from './DrawBox'; +export function drawDetections(canvasArg, detections) { + const detectionsArray = Array.isArray(detections) ? detections : [detections]; + detectionsArray.forEach(det => { + const score = det instanceof FaceDetection + ? det.score + : (isWithFaceDetection(det) ? det.detection.score : undefined); + const box = det instanceof FaceDetection + ? det.box + : (isWithFaceDetection(det) ? det.detection.box : new Box(det)); + const label = score ? `${round(score)}` : undefined; + new DrawBox(box, { label }).draw(canvasArg); + }); +} +//# sourceMappingURL=drawDetections.js.map \ No newline at end of file diff --git a/build/draw/drawDetections.js.map b/build/draw/drawDetections.js.map new file mode 100644 index 0000000..b8ad19a --- /dev/null +++ b/build/draw/drawDetections.js.map @@ -0,0 +1 @@ +{"version":3,"file":"drawDetections.js","sourceRoot":"","sources":["../../src/draw/drawDetections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAuB,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAqB,MAAM,gCAAgC,CAAC;AACxF,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,UAAU,cAAc,CAC5B,SAAqC,EACrC,UAA8D;IAE9D,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;IAE7E,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QAC5B,MAAM,KAAK,GAAG,GAAG,YAAY,aAAa;YACxC,CAAC,CAAC,GAAG,CAAC,KAAK;YACX,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QAEhE,MAAM,GAAG,GAAG,GAAG,YAAY,aAAa;YACtC,CAAC,CAAC,GAAG,CAAC,GAAG;YACT,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QAEjE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;QACnD,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/draw/drawFaceExpressions.d.ts b/build/draw/drawFaceExpressions.d.ts new file mode 100644 index 0000000..f96cc10 --- /dev/null +++ b/build/draw/drawFaceExpressions.d.ts @@ -0,0 +1,5 @@ +import { IPoint } from '../classes'; +import { FaceExpressions } from '../faceExpressionNet'; +import { WithFaceExpressions } from '../factories/WithFaceExpressions'; +export declare type DrawFaceExpressionsInput = FaceExpressions | WithFaceExpressions<{}>; +export declare function drawFaceExpressions(canvasArg: string | HTMLCanvasElement, faceExpressions: DrawFaceExpressionsInput | Array, minConfidence?: number, textFieldAnchor?: IPoint): void; diff --git a/build/draw/drawFaceExpressions.js b/build/draw/drawFaceExpressions.js new file mode 100644 index 0000000..3292c22 --- /dev/null +++ b/build/draw/drawFaceExpressions.js @@ -0,0 +1,25 @@ +import { Point } from '../classes'; +import { FaceExpressions } from '../faceExpressionNet'; +import { isWithFaceDetection } from '../factories/WithFaceDetection'; +import { isWithFaceExpressions } from '../factories/WithFaceExpressions'; +import { round } from '../utils'; +import { DrawTextField } from './DrawTextField'; +export function drawFaceExpressions(canvasArg, faceExpressions, minConfidence = 0.1, textFieldAnchor) { + const faceExpressionsArray = Array.isArray(faceExpressions) ? faceExpressions : [faceExpressions]; + faceExpressionsArray.forEach(e => { + const expr = e instanceof FaceExpressions + ? e + : (isWithFaceExpressions(e) ? e.expressions : undefined); + if (!expr) { + throw new Error('drawFaceExpressions - expected faceExpressions to be FaceExpressions | WithFaceExpressions<{}> or array thereof'); + } + const sorted = expr.asSortedArray(); + const resultsToDisplay = sorted.filter(expr => expr.probability > minConfidence); + const anchor = isWithFaceDetection(e) + ? e.detection.box.bottomLeft + : (textFieldAnchor || new Point(0, 0)); + const drawTextField = new DrawTextField(resultsToDisplay.map(expr => `${expr.expression} (${round(expr.probability)})`), anchor); + drawTextField.draw(canvasArg); + }); +} +//# sourceMappingURL=drawFaceExpressions.js.map \ No newline at end of file diff --git a/build/draw/drawFaceExpressions.js.map b/build/draw/drawFaceExpressions.js.map new file mode 100644 index 0000000..2e6d902 --- /dev/null +++ b/build/draw/drawFaceExpressions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"drawFaceExpressions.js","sourceRoot":"","sources":["../../src/draw/drawFaceExpressions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAuB,MAAM,kCAAkC,CAAC;AAC9F,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhD,MAAM,UAAU,mBAAmB,CACjC,SAAqC,EACrC,eAA2E,EAC3E,aAAa,GAAG,GAAG,EACnB,eAAwB;IAExB,MAAM,oBAAoB,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAA;IAEjG,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QAC/B,MAAM,IAAI,GAAG,CAAC,YAAY,eAAe;YACvC,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QAC1D,IAAI,CAAC,IAAI,EAAE;YACT,MAAM,IAAI,KAAK,CAAC,iHAAiH,CAAC,CAAA;SACnI;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;QACnC,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC,CAAA;QAEhF,MAAM,MAAM,GAAG,mBAAmB,CAAC,CAAC,CAAC;YACnC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU;YAC5B,CAAC,CAAC,CAAC,eAAe,IAAI,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAExC,MAAM,aAAa,GAAG,IAAI,aAAa,CACrC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAC/E,MAAM,CACP,CAAA;QACD,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/draw/index.d.ts b/build/draw/index.d.ts new file mode 100644 index 0000000..520d940 --- /dev/null +++ b/build/draw/index.d.ts @@ -0,0 +1,6 @@ +export * from './drawContour'; +export * from './drawDetections'; +export * from './drawFaceExpressions'; +export * from './DrawBox'; +export * from './DrawFaceLandmarks'; +export * from './DrawTextField'; diff --git a/build/draw/index.js b/build/draw/index.js new file mode 100644 index 0000000..6e3f6d8 --- /dev/null +++ b/build/draw/index.js @@ -0,0 +1,7 @@ +export * from './drawContour'; +export * from './drawDetections'; +export * from './drawFaceExpressions'; +export * from './DrawBox'; +export * from './DrawFaceLandmarks'; +export * from './DrawTextField'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/draw/index.js.map b/build/draw/index.js.map new file mode 100644 index 0000000..3798149 --- /dev/null +++ b/build/draw/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/draw/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,WAAW,CAAA;AACzB,cAAc,qBAAqB,CAAA;AACnC,cAAc,iBAAiB,CAAA"} \ No newline at end of file diff --git a/build/env/createBrowserEnv.d.ts b/build/env/createBrowserEnv.d.ts new file mode 100644 index 0000000..f7f144c --- /dev/null +++ b/build/env/createBrowserEnv.d.ts @@ -0,0 +1,2 @@ +import { Environment } from './types'; +export declare function createBrowserEnv(): Environment; diff --git a/build/env/createBrowserEnv.js b/build/env/createBrowserEnv.js new file mode 100644 index 0000000..4243f3e --- /dev/null +++ b/build/env/createBrowserEnv.js @@ -0,0 +1,20 @@ +export function createBrowserEnv() { + const fetch = window['fetch'] || function () { + throw new Error('fetch - missing fetch implementation for browser environment'); + }; + const readFile = function () { + throw new Error('readFile - filesystem not available for browser environment'); + }; + return { + Canvas: HTMLCanvasElement, + CanvasRenderingContext2D: CanvasRenderingContext2D, + Image: HTMLImageElement, + ImageData: ImageData, + Video: HTMLVideoElement, + createCanvasElement: () => document.createElement('canvas'), + createImageElement: () => document.createElement('img'), + fetch, + readFile + }; +} +//# sourceMappingURL=createBrowserEnv.js.map \ No newline at end of file diff --git a/build/env/createBrowserEnv.js.map b/build/env/createBrowserEnv.js.map new file mode 100644 index 0000000..84a5722 --- /dev/null +++ b/build/env/createBrowserEnv.js.map @@ -0,0 +1 @@ +{"version":3,"file":"createBrowserEnv.js","sourceRoot":"","sources":["../../src/env/createBrowserEnv.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB;IAE9B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI;QAC/B,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;IACjF,CAAC,CAAA;IAED,MAAM,QAAQ,GAAG;QACf,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAA;IAChF,CAAC,CAAA;IAED,OAAO;QACL,MAAM,EAAE,iBAAiB;QACzB,wBAAwB,EAAE,wBAAwB;QAClD,KAAK,EAAE,gBAAgB;QACvB,SAAS,EAAE,SAAS;QACpB,KAAK,EAAE,gBAAgB;QACvB,mBAAmB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;QAC3D,kBAAkB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;QACvD,KAAK;QACL,QAAQ;KACT,CAAA;AACH,CAAC"} \ No newline at end of file diff --git a/build/env/createFileSystem.d.ts b/build/env/createFileSystem.d.ts new file mode 100644 index 0000000..9e53e28 --- /dev/null +++ b/build/env/createFileSystem.d.ts @@ -0,0 +1,2 @@ +import { FileSystem } from './types'; +export declare function createFileSystem(fs?: any): FileSystem; diff --git a/build/env/createFileSystem.js b/build/env/createFileSystem.js new file mode 100644 index 0000000..08efdf5 --- /dev/null +++ b/build/env/createFileSystem.js @@ -0,0 +1,26 @@ +export function createFileSystem(fs) { + let requireFsError = ''; + if (!fs) { + try { + fs = require('fs'); + } + catch (err) { + requireFsError = err.toString(); + } + } + const readFile = fs + ? function (filePath) { + return new Promise((res, rej) => { + fs.readFile(filePath, function (err, buffer) { + return err ? rej(err) : res(buffer); + }); + }); + } + : function () { + throw new Error(`readFile - failed to require fs in nodejs environment with error: ${requireFsError}`); + }; + return { + readFile + }; +} +//# sourceMappingURL=createFileSystem.js.map \ No newline at end of file diff --git a/build/env/createFileSystem.js.map b/build/env/createFileSystem.js.map new file mode 100644 index 0000000..7afcb9c --- /dev/null +++ b/build/env/createFileSystem.js.map @@ -0,0 +1 @@ +{"version":3,"file":"createFileSystem.js","sourceRoot":"","sources":["../../src/env/createFileSystem.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAAC,EAAQ;IAEvC,IAAI,cAAc,GAAG,EAAE,CAAA;IAEvB,IAAI,CAAC,EAAE,EAAE;QACP,IAAI;YACF,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;SACnB;QAAC,OAAO,GAAG,EAAE;YACZ,cAAc,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAA;SAChC;KACF;IAED,MAAM,QAAQ,GAAG,EAAE;QACjB,CAAC,CAAC,UAAS,QAAgB;YACzB,OAAO,IAAI,OAAO,CAAS,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;gBACtC,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAS,GAAQ,EAAE,MAAc;oBACrD,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;gBACrC,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,CAAC,CAAC;YACA,MAAM,IAAI,KAAK,CAAC,qEAAqE,cAAc,EAAE,CAAC,CAAA;QACxG,CAAC,CAAA;IAEH,OAAO;QACL,QAAQ;KACT,CAAA;AACH,CAAC"} \ No newline at end of file diff --git a/build/env/createNodejsEnv.d.ts b/build/env/createNodejsEnv.d.ts new file mode 100644 index 0000000..a64159b --- /dev/null +++ b/build/env/createNodejsEnv.d.ts @@ -0,0 +1,2 @@ +import { Environment } from './types'; +export declare function createNodejsEnv(): Environment; diff --git a/build/env/createNodejsEnv.js b/build/env/createNodejsEnv.js new file mode 100644 index 0000000..02a362d --- /dev/null +++ b/build/env/createNodejsEnv.js @@ -0,0 +1,38 @@ +import { createFileSystem } from './createFileSystem'; +export function createNodejsEnv() { + const Canvas = global['Canvas'] || global['HTMLCanvasElement']; + const Image = global['Image'] || global['HTMLImageElement']; + const createCanvasElement = function () { + if (Canvas) { + return new Canvas(); + } + throw new Error('createCanvasElement - missing Canvas implementation for nodejs environment'); + }; + const createImageElement = function () { + if (Image) { + return new Image(); + } + throw new Error('createImageElement - missing Image implementation for nodejs environment'); + }; + const fetch = global['fetch'] || function () { + throw new Error('fetch - missing fetch implementation for nodejs environment'); + }; + const fileSystem = createFileSystem(); + return { + Canvas: Canvas || class { + }, + CanvasRenderingContext2D: global['CanvasRenderingContext2D'] || class { + }, + Image: Image || class { + }, + ImageData: global['ImageData'] || class { + }, + Video: global['HTMLVideoElement'] || class { + }, + createCanvasElement, + createImageElement, + fetch, + ...fileSystem + }; +} +//# sourceMappingURL=createNodejsEnv.js.map \ No newline at end of file diff --git a/build/env/createNodejsEnv.js.map b/build/env/createNodejsEnv.js.map new file mode 100644 index 0000000..5cd998b --- /dev/null +++ b/build/env/createNodejsEnv.js.map @@ -0,0 +1 @@ +{"version":3,"file":"createNodejsEnv.js","sourceRoot":"","sources":["../../src/env/createNodejsEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,MAAM,UAAU,eAAe;IAE7B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,mBAAmB,CAAC,CAAA;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAE3D,MAAM,mBAAmB,GAAG;QAC1B,IAAI,MAAM,EAAE;YACV,OAAO,IAAI,MAAM,EAAE,CAAA;SACpB;QACD,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAA;IAC/F,CAAC,CAAA;IAED,MAAM,kBAAkB,GAAG;QACzB,IAAI,KAAK,EAAE;YACT,OAAO,IAAI,KAAK,EAAE,CAAA;SACnB;QACD,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAA;IAC7F,CAAC,CAAA;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI;QAC/B,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAA;IAChF,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAA;IAErC,OAAO;QACL,MAAM,EAAE,MAAM,IAAI;SAAQ;QAC1B,wBAAwB,EAAE,MAAM,CAAC,0BAA0B,CAAC,IAAI;SAAQ;QACxE,KAAK,EAAE,KAAK,IAAI;SAAQ;QACxB,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI;SAAQ;QAC1C,KAAK,EAAE,MAAM,CAAC,kBAAkB,CAAC,IAAI;SAAQ;QAC7C,mBAAmB;QACnB,kBAAkB;QAClB,KAAK;QACL,GAAG,UAAU;KACd,CAAA;AACH,CAAC"} \ No newline at end of file diff --git a/build/env/index.d.ts b/build/env/index.d.ts new file mode 100644 index 0000000..525a8ab --- /dev/null +++ b/build/env/index.d.ts @@ -0,0 +1,22 @@ +import { createBrowserEnv } from './createBrowserEnv'; +import { createFileSystem } from './createFileSystem'; +import { createNodejsEnv } from './createNodejsEnv'; +import { isBrowser } from './isBrowser'; +import { isNodejs } from './isNodejs'; +import { Environment } from './types'; +declare function getEnv(): Environment; +declare function setEnv(env: Environment): void; +declare function initialize(): void; +declare function monkeyPatch(env: Partial): void; +export declare const env: { + getEnv: typeof getEnv; + setEnv: typeof setEnv; + initialize: typeof initialize; + createBrowserEnv: typeof createBrowserEnv; + createFileSystem: typeof createFileSystem; + createNodejsEnv: typeof createNodejsEnv; + monkeyPatch: typeof monkeyPatch; + isBrowser: typeof isBrowser; + isNodejs: typeof isNodejs; +}; +export * from './types'; diff --git a/build/env/index.js b/build/env/index.js new file mode 100644 index 0000000..4a53eb1 --- /dev/null +++ b/build/env/index.js @@ -0,0 +1,56 @@ +import { createBrowserEnv } from './createBrowserEnv'; +import { createFileSystem } from './createFileSystem'; +import { createNodejsEnv } from './createNodejsEnv'; +import { isBrowser } from './isBrowser'; +import { isNodejs } from './isNodejs'; +let environment; +function getEnv() { + if (!environment) { + throw new Error('getEnv - environment is not defined, check isNodejs() and isBrowser()'); + } + return environment; +} +function setEnv(env) { + environment = env; +} +function initialize() { + // check for isBrowser() first to prevent electron renderer process + // to be initialized with wrong environment due to isNodejs() returning true + if (isBrowser()) { + return setEnv(createBrowserEnv()); + } + if (isNodejs()) { + return setEnv(createNodejsEnv()); + } +} +function monkeyPatch(env) { + if (!environment) { + initialize(); + } + if (!environment) { + throw new Error('monkeyPatch - environment is not defined, check isNodejs() and isBrowser()'); + } + const { Canvas = environment.Canvas, Image = environment.Image } = env; + environment.Canvas = Canvas; + environment.Image = Image; + environment.createCanvasElement = env.createCanvasElement || (() => new Canvas()); + environment.createImageElement = env.createImageElement || (() => new Image()); + environment.ImageData = env.ImageData || environment.ImageData; + environment.Video = env.Video || environment.Video; + environment.fetch = env.fetch || environment.fetch; + environment.readFile = env.readFile || environment.readFile; +} +export const env = { + getEnv, + setEnv, + initialize, + createBrowserEnv, + createFileSystem, + createNodejsEnv, + monkeyPatch, + isBrowser, + isNodejs +}; +initialize(); +export * from './types'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/env/index.js.map b/build/env/index.js.map new file mode 100644 index 0000000..3d80f8b --- /dev/null +++ b/build/env/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/env/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,IAAI,WAA+B,CAAA;AAEnC,SAAS,MAAM;IACb,IAAI,CAAC,WAAW,EAAE;QAChB,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAA;KACzF;IACD,OAAO,WAAW,CAAA;AACpB,CAAC;AAED,SAAS,MAAM,CAAC,GAAgB;IAC9B,WAAW,GAAG,GAAG,CAAA;AACnB,CAAC;AAED,SAAS,UAAU;IACjB,mEAAmE;IACnE,4EAA4E;IAC5E,IAAI,SAAS,EAAE,EAAE;QACf,OAAO,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAA;KAClC;IACD,IAAI,QAAQ,EAAE,EAAE;QACd,OAAO,MAAM,CAAC,eAAe,EAAE,CAAC,CAAA;KACjC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAyB;IAC5C,IAAI,CAAC,WAAW,EAAE;QAChB,UAAU,EAAE,CAAA;KACb;IAED,IAAI,CAAC,WAAW,EAAE;QAChB,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAA;KAC9F;IAED,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,GAAG,WAAW,CAAC,KAAK,EAAE,GAAG,GAAG,CAAA;IACtE,WAAW,CAAC,MAAM,GAAG,MAAM,CAAA;IAC3B,WAAW,CAAC,KAAK,GAAG,KAAK,CAAA;IACzB,WAAW,CAAC,mBAAmB,GAAG,GAAG,CAAC,mBAAmB,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,CAAA;IACjF,WAAW,CAAC,kBAAkB,GAAG,GAAG,CAAC,kBAAkB,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAA;IAE9E,WAAW,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,WAAW,CAAC,SAAS,CAAA;IAC9D,WAAW,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,WAAW,CAAC,KAAK,CAAA;IAClD,WAAW,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,WAAW,CAAC,KAAK,CAAA;IAClD,WAAW,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAA;AAC7D,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,MAAM;IACN,MAAM;IACN,UAAU;IACV,gBAAgB;IAChB,gBAAgB;IAChB,eAAe;IACf,WAAW;IACX,SAAS;IACT,QAAQ;CACT,CAAA;AAED,UAAU,EAAE,CAAA;AAEZ,cAAc,SAAS,CAAA"} \ No newline at end of file diff --git a/build/env/isBrowser.d.ts b/build/env/isBrowser.d.ts new file mode 100644 index 0000000..adcd129 --- /dev/null +++ b/build/env/isBrowser.d.ts @@ -0,0 +1 @@ +export declare function isBrowser(): boolean; diff --git a/build/env/isBrowser.js b/build/env/isBrowser.js new file mode 100644 index 0000000..d64a57b --- /dev/null +++ b/build/env/isBrowser.js @@ -0,0 +1,10 @@ +export function isBrowser() { + return typeof window === 'object' + && typeof document !== 'undefined' + && typeof HTMLImageElement !== 'undefined' + && typeof HTMLCanvasElement !== 'undefined' + && typeof HTMLVideoElement !== 'undefined' + && typeof ImageData !== 'undefined' + && typeof CanvasRenderingContext2D !== 'undefined'; +} +//# sourceMappingURL=isBrowser.js.map \ No newline at end of file diff --git a/build/env/isBrowser.js.map b/build/env/isBrowser.js.map new file mode 100644 index 0000000..8482cea --- /dev/null +++ b/build/env/isBrowser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"isBrowser.js","sourceRoot":"","sources":["../../src/env/isBrowser.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,MAAM,KAAK,QAAQ;WAC5B,OAAO,QAAQ,KAAK,WAAW;WAC/B,OAAO,gBAAgB,KAAK,WAAW;WACvC,OAAO,iBAAiB,KAAK,WAAW;WACxC,OAAO,gBAAgB,KAAK,WAAW;WACvC,OAAO,SAAS,KAAK,WAAW;WAChC,OAAO,wBAAwB,KAAK,WAAW,CAAA;AACtD,CAAC"} \ No newline at end of file diff --git a/build/env/isNodejs.d.ts b/build/env/isNodejs.d.ts new file mode 100644 index 0000000..6c90f35 --- /dev/null +++ b/build/env/isNodejs.d.ts @@ -0,0 +1 @@ +export declare function isNodejs(): boolean; diff --git a/build/env/isNodejs.js b/build/env/isNodejs.js new file mode 100644 index 0000000..60117fd --- /dev/null +++ b/build/env/isNodejs.js @@ -0,0 +1,9 @@ +export function isNodejs() { + return typeof global === 'object' + && typeof require === 'function' + && typeof module !== 'undefined' + // issues with gatsby.js: module.exports is undefined + // && !!module.exports + && typeof process !== 'undefined' && !!process.version; +} +//# sourceMappingURL=isNodejs.js.map \ No newline at end of file diff --git a/build/env/isNodejs.js.map b/build/env/isNodejs.js.map new file mode 100644 index 0000000..7da5c2d --- /dev/null +++ b/build/env/isNodejs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"isNodejs.js","sourceRoot":"","sources":["../../src/env/isNodejs.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ;IACtB,OAAO,OAAO,MAAM,KAAK,QAAQ;WAC5B,OAAO,OAAO,KAAK,UAAU;WAC7B,OAAO,MAAM,KAAK,WAAW;QAChC,qDAAqD;QACrD,sBAAsB;WACnB,OAAO,OAAO,KAAK,WAAW,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAA;AAC1D,CAAC"} \ No newline at end of file diff --git a/build/env/types.d.ts b/build/env/types.d.ts new file mode 100644 index 0000000..5337ab3 --- /dev/null +++ b/build/env/types.d.ts @@ -0,0 +1,14 @@ +/// +export declare type FileSystem = { + readFile: (filePath: string) => Promise; +}; +export declare type Environment = FileSystem & { + Canvas: typeof HTMLCanvasElement; + CanvasRenderingContext2D: typeof CanvasRenderingContext2D; + Image: typeof HTMLImageElement; + ImageData: typeof ImageData; + Video: typeof HTMLVideoElement; + createCanvasElement: () => HTMLCanvasElement; + createImageElement: () => HTMLImageElement; + fetch: (url: string, init?: RequestInit) => Promise; +}; diff --git a/build/env/types.js b/build/env/types.js new file mode 100644 index 0000000..5b2306a --- /dev/null +++ b/build/env/types.js @@ -0,0 +1 @@ +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/build/env/types.js.map b/build/env/types.js.map new file mode 100644 index 0000000..88cd32c --- /dev/null +++ b/build/env/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/env/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/euclideanDistance.d.ts b/build/euclideanDistance.d.ts new file mode 100644 index 0000000..d555de2 --- /dev/null +++ b/build/euclideanDistance.d.ts @@ -0,0 +1 @@ +export declare function euclideanDistance(arr1: number[] | Float32Array, arr2: number[] | Float32Array): number; diff --git a/build/euclideanDistance.js b/build/euclideanDistance.js new file mode 100644 index 0000000..04e3ca0 --- /dev/null +++ b/build/euclideanDistance.js @@ -0,0 +1,10 @@ +export function euclideanDistance(arr1, arr2) { + if (arr1.length !== arr2.length) + throw new Error('euclideanDistance: arr1.length !== arr2.length'); + const desc1 = Array.from(arr1); + const desc2 = Array.from(arr2); + return Math.sqrt(desc1 + .map((val, i) => val - desc2[i]) + .reduce((res, diff) => res + Math.pow(diff, 2), 0)); +} +//# sourceMappingURL=euclideanDistance.js.map \ No newline at end of file diff --git a/build/euclideanDistance.js.map b/build/euclideanDistance.js.map new file mode 100644 index 0000000..0f5a0d0 --- /dev/null +++ b/build/euclideanDistance.js.map @@ -0,0 +1 @@ +{"version":3,"file":"euclideanDistance.js","sourceRoot":"","sources":["../src/euclideanDistance.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAAC,IAA6B,EAAE,IAA6B;IAC5F,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAC7B,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;IAEnE,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE9B,OAAO,IAAI,CAAC,IAAI,CACd,KAAK;SACF,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;SAC/B,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CACrD,CAAA;AACH,CAAC"} \ No newline at end of file diff --git a/build/faceExpressionNet/FaceExpressionNet.d.ts b/build/faceExpressionNet/FaceExpressionNet.d.ts new file mode 100644 index 0000000..1fbed62 --- /dev/null +++ b/build/faceExpressionNet/FaceExpressionNet.d.ts @@ -0,0 +1,15 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { NetInput, TNetInput } from '../dom'; +import { FaceFeatureExtractor } from '../faceFeatureExtractor/FaceFeatureExtractor'; +import { FaceFeatureExtractorParams } from '../faceFeatureExtractor/types'; +import { FaceProcessor } from '../faceProcessor/FaceProcessor'; +import { FaceExpressions } from './FaceExpressions'; +export declare class FaceExpressionNet extends FaceProcessor { + constructor(faceFeatureExtractor?: FaceFeatureExtractor); + forwardInput(input: NetInput | tf.Tensor4D): tf.Tensor2D; + forward(input: TNetInput): Promise; + predictExpressions(input: TNetInput): Promise; + protected getDefaultModelName(): string; + protected getClassifierChannelsIn(): number; + protected getClassifierChannelsOut(): number; +} diff --git a/build/faceExpressionNet/FaceExpressionNet.js b/build/faceExpressionNet/FaceExpressionNet.js new file mode 100644 index 0000000..afbfe8f --- /dev/null +++ b/build/faceExpressionNet/FaceExpressionNet.js @@ -0,0 +1,41 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { toNetInput } from '../dom'; +import { FaceFeatureExtractor } from '../faceFeatureExtractor/FaceFeatureExtractor'; +import { FaceProcessor } from '../faceProcessor/FaceProcessor'; +import { FaceExpressions } from './FaceExpressions'; +export class FaceExpressionNet extends FaceProcessor { + constructor(faceFeatureExtractor = new FaceFeatureExtractor()) { + super('FaceExpressionNet', faceFeatureExtractor); + } + forwardInput(input) { + return tf.tidy(() => tf.softmax(this.runNet(input))); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + async predictExpressions(input) { + const netInput = await toNetInput(input); + const out = await this.forwardInput(netInput); + const probabilitesByBatch = await Promise.all(tf.unstack(out).map(async (t) => { + const data = await t.data(); + t.dispose(); + return data; + })); + out.dispose(); + const predictionsByBatch = probabilitesByBatch + .map(probabilites => new FaceExpressions(probabilites)); + return netInput.isBatchInput + ? predictionsByBatch + : predictionsByBatch[0]; + } + getDefaultModelName() { + return 'face_expression_model'; + } + getClassifierChannelsIn() { + return 256; + } + getClassifierChannelsOut() { + return 7; + } +} +//# sourceMappingURL=FaceExpressionNet.js.map \ No newline at end of file diff --git a/build/faceExpressionNet/FaceExpressionNet.js.map b/build/faceExpressionNet/FaceExpressionNet.js.map new file mode 100644 index 0000000..57f81ad --- /dev/null +++ b/build/faceExpressionNet/FaceExpressionNet.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FaceExpressionNet.js","sourceRoot":"","sources":["../../src/faceExpressionNet/FaceExpressionNet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAuB,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AAEpF,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,OAAO,iBAAkB,SAAQ,aAAyC;IAE9E,YAAY,uBAA6C,IAAI,oBAAoB,EAAE;QACjF,KAAK,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,CAAA;IAClD,CAAC;IAEM,YAAY,CAAC,KAA6B;QAC/C,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACtD,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,KAAgB;QACnC,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;IACnD,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAAC,KAAgB;QAC9C,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,CAAA;QACxC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;QAC7C,MAAM,mBAAmB,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,EAAC,CAAC,EAAC,EAAE;YAC1E,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;YAC3B,CAAC,CAAC,OAAO,EAAE,CAAA;YACX,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAC,CAAA;QACH,GAAG,CAAC,OAAO,EAAE,CAAA;QAEb,MAAM,kBAAkB,GAAG,mBAAmB;aAC3C,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,eAAe,CAAC,YAA4B,CAAC,CAAC,CAAA;QAEzE,OAAO,QAAQ,CAAC,YAAY;YAC1B,CAAC,CAAC,kBAAkB;YACpB,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAA;IAC3B,CAAC;IAES,mBAAmB;QAC3B,OAAO,uBAAuB,CAAA;IAChC,CAAC;IAES,uBAAuB;QAC/B,OAAO,GAAG,CAAA;IACZ,CAAC;IAES,wBAAwB;QAChC,OAAO,CAAC,CAAA;IACV,CAAC;CACF"} \ No newline at end of file diff --git a/build/faceExpressionNet/FaceExpressions.d.ts b/build/faceExpressionNet/FaceExpressions.d.ts new file mode 100644 index 0000000..4e01ae3 --- /dev/null +++ b/build/faceExpressionNet/FaceExpressions.d.ts @@ -0,0 +1,15 @@ +export declare const FACE_EXPRESSION_LABELS: string[]; +export declare class FaceExpressions { + neutral: number; + happy: number; + sad: number; + angry: number; + fearful: number; + disgusted: number; + surprised: number; + constructor(probabilities: number[] | Float32Array); + asSortedArray(): { + expression: string; + probability: number; + }[]; +} diff --git a/build/faceExpressionNet/FaceExpressions.js b/build/faceExpressionNet/FaceExpressions.js new file mode 100644 index 0000000..604c0fa --- /dev/null +++ b/build/faceExpressionNet/FaceExpressions.js @@ -0,0 +1,17 @@ +export const FACE_EXPRESSION_LABELS = ['neutral', 'happy', 'sad', 'angry', 'fearful', 'disgusted', 'surprised']; +export class FaceExpressions { + constructor(probabilities) { + if (probabilities.length !== 7) { + throw new Error(`FaceExpressions.constructor - expected probabilities.length to be 7, have: ${probabilities.length}`); + } + FACE_EXPRESSION_LABELS.forEach((expression, idx) => { + this[expression] = probabilities[idx]; + }); + } + asSortedArray() { + return FACE_EXPRESSION_LABELS + .map(expression => ({ expression, probability: this[expression] })) + .sort((e0, e1) => e1.probability - e0.probability); + } +} +//# sourceMappingURL=FaceExpressions.js.map \ No newline at end of file diff --git a/build/faceExpressionNet/FaceExpressions.js.map b/build/faceExpressionNet/FaceExpressions.js.map new file mode 100644 index 0000000..4982892 --- /dev/null +++ b/build/faceExpressionNet/FaceExpressions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FaceExpressions.js","sourceRoot":"","sources":["../../src/faceExpressionNet/FaceExpressions.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;AAE/G,MAAM,OAAO,eAAe;IAS1B,YAAY,aAAsC;QAChD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;YAC9B,MAAM,IAAI,KAAK,CAAC,8EAA8E,aAAa,CAAC,MAAM,EAAE,CAAC,CAAA;SACtH;QAED,sBAAsB,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,EAAE;YACjD,IAAI,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;QACvC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,aAAa;QACX,OAAO,sBAAsB;aAC1B,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,CAAC,UAAU,CAAW,EAAE,CAAC,CAAC;aAC5E,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC,CAAA;IACtD,CAAC;CACF"} \ No newline at end of file diff --git a/build/faceExpressionNet/index.d.ts b/build/faceExpressionNet/index.d.ts new file mode 100644 index 0000000..d79c683 --- /dev/null +++ b/build/faceExpressionNet/index.d.ts @@ -0,0 +1,2 @@ +export * from './FaceExpressionNet'; +export * from './FaceExpressions'; diff --git a/build/faceExpressionNet/index.js b/build/faceExpressionNet/index.js new file mode 100644 index 0000000..40ccccb --- /dev/null +++ b/build/faceExpressionNet/index.js @@ -0,0 +1,3 @@ +export * from './FaceExpressionNet'; +export * from './FaceExpressions'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/faceExpressionNet/index.js.map b/build/faceExpressionNet/index.js.map new file mode 100644 index 0000000..2d00583 --- /dev/null +++ b/build/faceExpressionNet/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceExpressionNet/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"} \ No newline at end of file diff --git a/build/faceFeatureExtractor/FaceFeatureExtractor.d.ts b/build/faceFeatureExtractor/FaceFeatureExtractor.d.ts new file mode 100644 index 0000000..bfa5f24 --- /dev/null +++ b/build/faceFeatureExtractor/FaceFeatureExtractor.d.ts @@ -0,0 +1,18 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { NetInput, TNetInput } from '../dom'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { FaceFeatureExtractorParams, IFaceFeatureExtractor } from './types'; +export declare class FaceFeatureExtractor extends NeuralNetwork implements IFaceFeatureExtractor { + constructor(); + forwardInput(input: NetInput): tf.Tensor4D; + forward(input: TNetInput): Promise; + protected getDefaultModelName(): string; + protected extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap): { + params: FaceFeatureExtractorParams; + paramMappings: import("../common").ParamMapping[]; + }; + protected extractParams(weights: Float32Array): { + params: FaceFeatureExtractorParams; + paramMappings: import("../common").ParamMapping[]; + }; +} diff --git a/build/faceFeatureExtractor/FaceFeatureExtractor.js b/build/faceFeatureExtractor/FaceFeatureExtractor.js new file mode 100644 index 0000000..fa0b16d --- /dev/null +++ b/build/faceFeatureExtractor/FaceFeatureExtractor.js @@ -0,0 +1,42 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { toNetInput } from '../dom'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { normalize } from '../ops'; +import { denseBlock4 } from './denseBlock'; +import { extractParams } from './extractParams'; +import { extractParamsFromWeigthMap } from './extractParamsFromWeigthMap'; +export class FaceFeatureExtractor extends NeuralNetwork { + constructor() { + super('FaceFeatureExtractor'); + } + forwardInput(input) { + const { params } = this; + if (!params) { + throw new Error('FaceFeatureExtractor - load model before inference'); + } + return tf.tidy(() => { + const batchTensor = input.toBatchTensor(112, true); + const meanRgb = [122.782, 117.001, 104.298]; + const normalized = normalize(batchTensor, meanRgb).div(tf.scalar(255)); + let out = denseBlock4(normalized, params.dense0, true); + out = denseBlock4(out, params.dense1); + out = denseBlock4(out, params.dense2); + out = denseBlock4(out, params.dense3); + out = tf.avgPool(out, [7, 7], [2, 2], 'valid'); + return out; + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + getDefaultModelName() { + return 'face_feature_extractor_model'; + } + extractParamsFromWeigthMap(weightMap) { + return extractParamsFromWeigthMap(weightMap); + } + extractParams(weights) { + return extractParams(weights); + } +} +//# sourceMappingURL=FaceFeatureExtractor.js.map \ No newline at end of file diff --git a/build/faceFeatureExtractor/FaceFeatureExtractor.js.map b/build/faceFeatureExtractor/FaceFeatureExtractor.js.map new file mode 100644 index 0000000..1f16b85 --- /dev/null +++ b/build/faceFeatureExtractor/FaceFeatureExtractor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FaceFeatureExtractor.js","sourceRoot":"","sources":["../../src/faceFeatureExtractor/FaceFeatureExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAuB,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAG1E,MAAM,OAAO,oBAAqB,SAAQ,aAAyC;IAEjF;QACE,KAAK,CAAC,sBAAsB,CAAC,CAAA;IAC/B,CAAC;IAEM,YAAY,CAAC,KAAe;QAEjC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;QAEvB,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;SACtE;QAED,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;YAClB,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;YAClD,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;YAC3C,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAgB,CAAA;YAErF,IAAI,GAAG,GAAG,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACtD,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACrC,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACrC,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACrC,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;YAE9C,OAAO,GAAG,CAAA;QACZ,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,KAAgB;QACnC,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;IACnD,CAAC;IAES,mBAAmB;QAC3B,OAAO,8BAA8B,CAAA;IACvC,CAAC;IAES,0BAA0B,CAAC,SAA4B;QAC/D,OAAO,0BAA0B,CAAC,SAAS,CAAC,CAAA;IAC9C,CAAC;IAES,aAAa,CAAC,OAAqB;QAC3C,OAAO,aAAa,CAAC,OAAO,CAAC,CAAA;IAC/B,CAAC;CACF"} \ No newline at end of file diff --git a/build/faceFeatureExtractor/TinyFaceFeatureExtractor.d.ts b/build/faceFeatureExtractor/TinyFaceFeatureExtractor.d.ts new file mode 100644 index 0000000..d164353 --- /dev/null +++ b/build/faceFeatureExtractor/TinyFaceFeatureExtractor.d.ts @@ -0,0 +1,18 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { NetInput, TNetInput } from '../dom'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { IFaceFeatureExtractor, TinyFaceFeatureExtractorParams } from './types'; +export declare class TinyFaceFeatureExtractor extends NeuralNetwork implements IFaceFeatureExtractor { + constructor(); + forwardInput(input: NetInput): tf.Tensor4D; + forward(input: TNetInput): Promise; + protected getDefaultModelName(): string; + protected extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap): { + params: TinyFaceFeatureExtractorParams; + paramMappings: import("../common").ParamMapping[]; + }; + protected extractParams(weights: Float32Array): { + params: TinyFaceFeatureExtractorParams; + paramMappings: import("../common").ParamMapping[]; + }; +} diff --git a/build/faceFeatureExtractor/TinyFaceFeatureExtractor.js b/build/faceFeatureExtractor/TinyFaceFeatureExtractor.js new file mode 100644 index 0000000..ef167e2 --- /dev/null +++ b/build/faceFeatureExtractor/TinyFaceFeatureExtractor.js @@ -0,0 +1,41 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { toNetInput } from '../dom'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { normalize } from '../ops'; +import { denseBlock3 } from './denseBlock'; +import { extractParamsFromWeigthMapTiny } from './extractParamsFromWeigthMapTiny'; +import { extractParamsTiny } from './extractParamsTiny'; +export class TinyFaceFeatureExtractor extends NeuralNetwork { + constructor() { + super('TinyFaceFeatureExtractor'); + } + forwardInput(input) { + const { params } = this; + if (!params) { + throw new Error('TinyFaceFeatureExtractor - load model before inference'); + } + return tf.tidy(() => { + const batchTensor = input.toBatchTensor(112, true); + const meanRgb = [122.782, 117.001, 104.298]; + const normalized = normalize(batchTensor, meanRgb).div(tf.scalar(255)); + let out = denseBlock3(normalized, params.dense0, true); + out = denseBlock3(out, params.dense1); + out = denseBlock3(out, params.dense2); + out = tf.avgPool(out, [14, 14], [2, 2], 'valid'); + return out; + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + getDefaultModelName() { + return 'face_feature_extractor_tiny_model'; + } + extractParamsFromWeigthMap(weightMap) { + return extractParamsFromWeigthMapTiny(weightMap); + } + extractParams(weights) { + return extractParamsTiny(weights); + } +} +//# sourceMappingURL=TinyFaceFeatureExtractor.js.map \ No newline at end of file diff --git a/build/faceFeatureExtractor/TinyFaceFeatureExtractor.js.map b/build/faceFeatureExtractor/TinyFaceFeatureExtractor.js.map new file mode 100644 index 0000000..a4133b7 --- /dev/null +++ b/build/faceFeatureExtractor/TinyFaceFeatureExtractor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"TinyFaceFeatureExtractor.js","sourceRoot":"","sources":["../../src/faceFeatureExtractor/TinyFaceFeatureExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAuB,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,OAAO,wBAAyB,SAAQ,aAA6C;IAEzF;QACE,KAAK,CAAC,0BAA0B,CAAC,CAAA;IACnC,CAAC;IAEM,YAAY,CAAC,KAAe;QAEjC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;QAEvB,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAA;SAC1E;QAED,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;YAClB,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;YAClD,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;YAC3C,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAgB,CAAA;YAErF,IAAI,GAAG,GAAG,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACtD,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACrC,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACrC,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;YAEhD,OAAO,GAAG,CAAA;QACZ,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,KAAgB;QACnC,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;IACnD,CAAC;IAES,mBAAmB;QAC3B,OAAO,mCAAmC,CAAA;IAC5C,CAAC;IAES,0BAA0B,CAAC,SAA4B;QAC/D,OAAO,8BAA8B,CAAC,SAAS,CAAC,CAAA;IAClD,CAAC;IAES,aAAa,CAAC,OAAqB;QAC3C,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAA;IACnC,CAAC;CACF"} \ No newline at end of file diff --git a/build/faceFeatureExtractor/denseBlock.d.ts b/build/faceFeatureExtractor/denseBlock.d.ts new file mode 100644 index 0000000..685af3b --- /dev/null +++ b/build/faceFeatureExtractor/denseBlock.d.ts @@ -0,0 +1,4 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { DenseBlock3Params, DenseBlock4Params } from './types'; +export declare function denseBlock3(x: tf.Tensor4D, denseBlockParams: DenseBlock3Params, isFirstLayer?: boolean): tf.Tensor4D; +export declare function denseBlock4(x: tf.Tensor4D, denseBlockParams: DenseBlock4Params, isFirstLayer?: boolean, isScaleDown?: boolean): tf.Tensor4D; diff --git a/build/faceFeatureExtractor/denseBlock.js b/build/faceFeatureExtractor/denseBlock.js new file mode 100644 index 0000000..ec9e68a --- /dev/null +++ b/build/faceFeatureExtractor/denseBlock.js @@ -0,0 +1,27 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { depthwiseSeparableConv } from '../common/depthwiseSeparableConv'; +export function denseBlock3(x, denseBlockParams, isFirstLayer = false) { + return tf.tidy(() => { + const out1 = tf.relu(isFirstLayer + ? tf.add(tf.conv2d(x, denseBlockParams.conv0.filters, [2, 2], 'same'), denseBlockParams.conv0.bias) + : depthwiseSeparableConv(x, denseBlockParams.conv0, [2, 2])); + const out2 = depthwiseSeparableConv(out1, denseBlockParams.conv1, [1, 1]); + const in3 = tf.relu(tf.add(out1, out2)); + const out3 = depthwiseSeparableConv(in3, denseBlockParams.conv2, [1, 1]); + return tf.relu(tf.add(out1, tf.add(out2, out3))); + }); +} +export function denseBlock4(x, denseBlockParams, isFirstLayer = false, isScaleDown = true) { + return tf.tidy(() => { + const out1 = tf.relu(isFirstLayer + ? tf.add(tf.conv2d(x, denseBlockParams.conv0.filters, isScaleDown ? [2, 2] : [1, 1], 'same'), denseBlockParams.conv0.bias) + : depthwiseSeparableConv(x, denseBlockParams.conv0, isScaleDown ? [2, 2] : [1, 1])); + const out2 = depthwiseSeparableConv(out1, denseBlockParams.conv1, [1, 1]); + const in3 = tf.relu(tf.add(out1, out2)); + const out3 = depthwiseSeparableConv(in3, denseBlockParams.conv2, [1, 1]); + const in4 = tf.relu(tf.add(out1, tf.add(out2, out3))); + const out4 = depthwiseSeparableConv(in4, denseBlockParams.conv3, [1, 1]); + return tf.relu(tf.add(out1, tf.add(out2, tf.add(out3, out4)))); + }); +} +//# sourceMappingURL=denseBlock.js.map \ No newline at end of file diff --git a/build/faceFeatureExtractor/denseBlock.js.map b/build/faceFeatureExtractor/denseBlock.js.map new file mode 100644 index 0000000..dd1c115 --- /dev/null +++ b/build/faceFeatureExtractor/denseBlock.js.map @@ -0,0 +1 @@ +{"version":3,"file":"denseBlock.js","sourceRoot":"","sources":["../../src/faceFeatureExtractor/denseBlock.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/faceFeatureExtractor/extractParams.d.ts b/build/faceFeatureExtractor/extractParams.d.ts new file mode 100644 index 0000000..4b4b30f --- /dev/null +++ b/build/faceFeatureExtractor/extractParams.d.ts @@ -0,0 +1,6 @@ +import { ParamMapping } from '../common'; +import { FaceFeatureExtractorParams } from './types'; +export declare function extractParams(weights: Float32Array): { + params: FaceFeatureExtractorParams; + paramMappings: ParamMapping[]; +}; diff --git a/build/faceFeatureExtractor/extractParams.js b/build/faceFeatureExtractor/extractParams.js new file mode 100644 index 0000000..053e843 --- /dev/null +++ b/build/faceFeatureExtractor/extractParams.js @@ -0,0 +1,19 @@ +import { extractWeightsFactory } from '../common'; +import { extractorsFactory } from './extractorsFactory'; +export function extractParams(weights) { + const paramMappings = []; + const { extractWeights, getRemainingWeights } = extractWeightsFactory(weights); + const { extractDenseBlock4Params } = extractorsFactory(extractWeights, paramMappings); + const dense0 = extractDenseBlock4Params(3, 32, 'dense0', true); + const dense1 = extractDenseBlock4Params(32, 64, 'dense1'); + const dense2 = extractDenseBlock4Params(64, 128, 'dense2'); + const dense3 = extractDenseBlock4Params(128, 256, 'dense3'); + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { + paramMappings, + params: { dense0, dense1, dense2, dense3 } + }; +} +//# sourceMappingURL=extractParams.js.map \ No newline at end of file diff --git a/build/faceFeatureExtractor/extractParams.js.map b/build/faceFeatureExtractor/extractParams.js.map new file mode 100644 index 0000000..bf2faab --- /dev/null +++ b/build/faceFeatureExtractor/extractParams.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParams.js","sourceRoot":"","sources":["../../src/faceFeatureExtractor/extractParams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAgB,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAIxD,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,EACJ,wBAAwB,EACzB,GAAG,iBAAiB,CAAC,cAAc,EAAE,aAAa,CAAC,CAAA;IAEpD,MAAM,MAAM,GAAG,wBAAwB,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;IAC9D,MAAM,MAAM,GAAG,wBAAwB,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAA;IACzD,MAAM,MAAM,GAAG,wBAAwB,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,wBAAwB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;IAE3D,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,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;KAC3C,CAAA;AACH,CAAC"} \ No newline at end of file diff --git a/build/faceFeatureExtractor/extractParamsFromWeigthMap.d.ts b/build/faceFeatureExtractor/extractParamsFromWeigthMap.d.ts new file mode 100644 index 0000000..9e2eb25 --- /dev/null +++ b/build/faceFeatureExtractor/extractParamsFromWeigthMap.d.ts @@ -0,0 +1,7 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { ParamMapping } from '../common'; +import { FaceFeatureExtractorParams } from './types'; +export declare function extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap): { + params: FaceFeatureExtractorParams; + paramMappings: ParamMapping[]; +}; diff --git a/build/faceFeatureExtractor/extractParamsFromWeigthMap.js b/build/faceFeatureExtractor/extractParamsFromWeigthMap.js new file mode 100644 index 0000000..7f6e4b8 --- /dev/null +++ b/build/faceFeatureExtractor/extractParamsFromWeigthMap.js @@ -0,0 +1,15 @@ +import { disposeUnusedWeightTensors } from '../common'; +import { loadParamsFactory } from './loadParamsFactory'; +export function extractParamsFromWeigthMap(weightMap) { + const paramMappings = []; + const { extractDenseBlock4Params } = loadParamsFactory(weightMap, paramMappings); + const params = { + dense0: extractDenseBlock4Params('dense0', true), + dense1: extractDenseBlock4Params('dense1'), + dense2: extractDenseBlock4Params('dense2'), + dense3: extractDenseBlock4Params('dense3') + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} +//# sourceMappingURL=extractParamsFromWeigthMap.js.map \ No newline at end of file diff --git a/build/faceFeatureExtractor/extractParamsFromWeigthMap.js.map b/build/faceFeatureExtractor/extractParamsFromWeigthMap.js.map new file mode 100644 index 0000000..24f7db7 --- /dev/null +++ b/build/faceFeatureExtractor/extractParamsFromWeigthMap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParamsFromWeigthMap.js","sourceRoot":"","sources":["../../src/faceFeatureExtractor/extractParamsFromWeigthMap.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,0BAA0B,EAAgB,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,UAAU,0BAA0B,CACxC,SAA4B;IAG5B,MAAM,aAAa,GAAmB,EAAE,CAAA;IAExC,MAAM,EACJ,wBAAwB,EACzB,GAAG,iBAAiB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAE/C,MAAM,MAAM,GAAG;QACb,MAAM,EAAE,wBAAwB,CAAC,QAAQ,EAAE,IAAI,CAAC;QAChD,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CAAC;QAC1C,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CAAC;QAC1C,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CAAC;KAC3C,CAAA;IAED,0BAA0B,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAEpD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAA;AAClC,CAAC"} \ No newline at end of file diff --git a/build/faceFeatureExtractor/extractParamsFromWeigthMapTiny.d.ts b/build/faceFeatureExtractor/extractParamsFromWeigthMapTiny.d.ts new file mode 100644 index 0000000..ec21713 --- /dev/null +++ b/build/faceFeatureExtractor/extractParamsFromWeigthMapTiny.d.ts @@ -0,0 +1,7 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { ParamMapping } from '../common'; +import { TinyFaceFeatureExtractorParams } from './types'; +export declare function extractParamsFromWeigthMapTiny(weightMap: tf.NamedTensorMap): { + params: TinyFaceFeatureExtractorParams; + paramMappings: ParamMapping[]; +}; diff --git a/build/faceFeatureExtractor/extractParamsFromWeigthMapTiny.js b/build/faceFeatureExtractor/extractParamsFromWeigthMapTiny.js new file mode 100644 index 0000000..2f873cf --- /dev/null +++ b/build/faceFeatureExtractor/extractParamsFromWeigthMapTiny.js @@ -0,0 +1,14 @@ +import { disposeUnusedWeightTensors } from '../common'; +import { loadParamsFactory } from './loadParamsFactory'; +export function extractParamsFromWeigthMapTiny(weightMap) { + const paramMappings = []; + const { extractDenseBlock3Params } = loadParamsFactory(weightMap, paramMappings); + const params = { + dense0: extractDenseBlock3Params('dense0', true), + dense1: extractDenseBlock3Params('dense1'), + dense2: extractDenseBlock3Params('dense2') + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} +//# sourceMappingURL=extractParamsFromWeigthMapTiny.js.map \ No newline at end of file diff --git a/build/faceFeatureExtractor/extractParamsFromWeigthMapTiny.js.map b/build/faceFeatureExtractor/extractParamsFromWeigthMapTiny.js.map new file mode 100644 index 0000000..6649114 --- /dev/null +++ b/build/faceFeatureExtractor/extractParamsFromWeigthMapTiny.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParamsFromWeigthMapTiny.js","sourceRoot":"","sources":["../../src/faceFeatureExtractor/extractParamsFromWeigthMapTiny.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,0BAA0B,EAAgB,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,UAAU,8BAA8B,CAC5C,SAA4B;IAG5B,MAAM,aAAa,GAAmB,EAAE,CAAA;IAExC,MAAM,EACJ,wBAAwB,EACzB,GAAG,iBAAiB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAE/C,MAAM,MAAM,GAAG;QACb,MAAM,EAAE,wBAAwB,CAAC,QAAQ,EAAE,IAAI,CAAC;QAChD,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CAAC;QAC1C,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CAAC;KAC3C,CAAA;IAED,0BAA0B,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAEpD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAA;AAClC,CAAC"} \ No newline at end of file diff --git a/build/faceFeatureExtractor/extractParamsTiny.d.ts b/build/faceFeatureExtractor/extractParamsTiny.d.ts new file mode 100644 index 0000000..583fc92 --- /dev/null +++ b/build/faceFeatureExtractor/extractParamsTiny.d.ts @@ -0,0 +1,6 @@ +import { ParamMapping } from '../common'; +import { TinyFaceFeatureExtractorParams } from './types'; +export declare function extractParamsTiny(weights: Float32Array): { + params: TinyFaceFeatureExtractorParams; + paramMappings: ParamMapping[]; +}; diff --git a/build/faceFeatureExtractor/extractParamsTiny.js b/build/faceFeatureExtractor/extractParamsTiny.js new file mode 100644 index 0000000..61e5a6e --- /dev/null +++ b/build/faceFeatureExtractor/extractParamsTiny.js @@ -0,0 +1,18 @@ +import { extractWeightsFactory } from '../common'; +import { extractorsFactory } from './extractorsFactory'; +export function extractParamsTiny(weights) { + const paramMappings = []; + const { extractWeights, getRemainingWeights } = extractWeightsFactory(weights); + const { extractDenseBlock3Params } = extractorsFactory(extractWeights, paramMappings); + const dense0 = extractDenseBlock3Params(3, 32, 'dense0', true); + const dense1 = extractDenseBlock3Params(32, 64, 'dense1'); + const dense2 = extractDenseBlock3Params(64, 128, 'dense2'); + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { + paramMappings, + params: { dense0, dense1, dense2 } + }; +} +//# sourceMappingURL=extractParamsTiny.js.map \ No newline at end of file diff --git a/build/faceFeatureExtractor/extractParamsTiny.js.map b/build/faceFeatureExtractor/extractParamsTiny.js.map new file mode 100644 index 0000000..782843e --- /dev/null +++ b/build/faceFeatureExtractor/extractParamsTiny.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParamsTiny.js","sourceRoot":"","sources":["../../src/faceFeatureExtractor/extractParamsTiny.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAgB,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAKxD,MAAM,UAAU,iBAAiB,CAAC,OAAqB;IAErD,MAAM,aAAa,GAAmB,EAAE,CAAA;IAExC,MAAM,EACJ,cAAc,EACd,mBAAmB,EACpB,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;IAElC,MAAM,EACJ,wBAAwB,EACzB,GAAG,iBAAiB,CAAC,cAAc,EAAE,aAAa,CAAC,CAAA;IAEpD,MAAM,MAAM,GAAG,wBAAwB,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;IAC9D,MAAM,MAAM,GAAG,wBAAwB,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAA;IACzD,MAAM,MAAM,GAAG,wBAAwB,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;IAE1D,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,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;KACnC,CAAA;AACH,CAAC"} \ No newline at end of file diff --git a/build/faceFeatureExtractor/extractorsFactory.d.ts b/build/faceFeatureExtractor/extractorsFactory.d.ts new file mode 100644 index 0000000..93ca270 --- /dev/null +++ b/build/faceFeatureExtractor/extractorsFactory.d.ts @@ -0,0 +1,6 @@ +import { ExtractWeightsFunction, ParamMapping } from '../common'; +import { DenseBlock3Params, DenseBlock4Params } from './types'; +export declare function extractorsFactory(extractWeights: ExtractWeightsFunction, paramMappings: ParamMapping[]): { + extractDenseBlock3Params: (channelsIn: number, channelsOut: number, mappedPrefix: string, isFirstLayer?: boolean) => DenseBlock3Params; + extractDenseBlock4Params: (channelsIn: number, channelsOut: number, mappedPrefix: string, isFirstLayer?: boolean) => DenseBlock4Params; +}; diff --git a/build/faceFeatureExtractor/extractorsFactory.js b/build/faceFeatureExtractor/extractorsFactory.js new file mode 100644 index 0000000..721392d --- /dev/null +++ b/build/faceFeatureExtractor/extractorsFactory.js @@ -0,0 +1,23 @@ +import { extractConvParamsFactory, extractSeparableConvParamsFactory, } from '../common'; +export function extractorsFactory(extractWeights, paramMappings) { + const extractConvParams = extractConvParamsFactory(extractWeights, paramMappings); + const extractSeparableConvParams = extractSeparableConvParamsFactory(extractWeights, paramMappings); + function extractDenseBlock3Params(channelsIn, channelsOut, mappedPrefix, isFirstLayer = false) { + const conv0 = isFirstLayer + ? extractConvParams(channelsIn, channelsOut, 3, `${mappedPrefix}/conv0`) + : extractSeparableConvParams(channelsIn, channelsOut, `${mappedPrefix}/conv0`); + const conv1 = extractSeparableConvParams(channelsOut, channelsOut, `${mappedPrefix}/conv1`); + const conv2 = extractSeparableConvParams(channelsOut, channelsOut, `${mappedPrefix}/conv2`); + return { conv0, conv1, conv2 }; + } + function extractDenseBlock4Params(channelsIn, channelsOut, mappedPrefix, isFirstLayer = false) { + const { conv0, conv1, conv2 } = extractDenseBlock3Params(channelsIn, channelsOut, mappedPrefix, isFirstLayer); + const conv3 = extractSeparableConvParams(channelsOut, channelsOut, `${mappedPrefix}/conv3`); + return { conv0, conv1, conv2, conv3 }; + } + return { + extractDenseBlock3Params, + extractDenseBlock4Params + }; +} +//# sourceMappingURL=extractorsFactory.js.map \ No newline at end of file diff --git a/build/faceFeatureExtractor/extractorsFactory.js.map b/build/faceFeatureExtractor/extractorsFactory.js.map new file mode 100644 index 0000000..639df6b --- /dev/null +++ b/build/faceFeatureExtractor/extractorsFactory.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractorsFactory.js","sourceRoot":"","sources":["../../src/faceFeatureExtractor/extractorsFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,iCAAiC,GAGlC,MAAM,WAAW,CAAC;AAGnB,MAAM,UAAU,iBAAiB,CAAC,cAAsC,EAAE,aAA6B;IAErG,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,cAAc,EAAE,aAAa,CAAC,CAAA;IACjF,MAAM,0BAA0B,GAAG,iCAAiC,CAAC,cAAc,EAAE,aAAa,CAAC,CAAA;IAEnG,SAAS,wBAAwB,CAAC,UAAkB,EAAE,WAAmB,EAAE,YAAoB,EAAE,eAAwB,KAAK;QAE5H,MAAM,KAAK,GAAG,YAAY;YACxB,CAAC,CAAC,iBAAiB,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,EAAE,GAAG,YAAY,QAAQ,CAAC;YACxE,CAAC,CAAC,0BAA0B,CAAC,UAAU,EAAE,WAAW,EAAE,GAAG,YAAY,QAAQ,CAAC,CAAA;QAChF,MAAM,KAAK,GAAG,0BAA0B,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,YAAY,QAAQ,CAAC,CAAA;QAC3F,MAAM,KAAK,GAAG,0BAA0B,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,YAAY,QAAQ,CAAC,CAAA;QAE3F,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IAChC,CAAC;IAED,SAAS,wBAAwB,CAAC,UAAkB,EAAE,WAAmB,EAAE,YAAoB,EAAE,eAAwB,KAAK;QAE5H,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,wBAAwB,CAAC,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,CAAC,CAAA;QAC7G,MAAM,KAAK,GAAG,0BAA0B,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,YAAY,QAAQ,CAAC,CAAA;QAE3F,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IACvC,CAAC;IAED,OAAO;QACL,wBAAwB;QACxB,wBAAwB;KACzB,CAAA;AAEH,CAAC"} \ No newline at end of file diff --git a/build/faceFeatureExtractor/index.d.ts b/build/faceFeatureExtractor/index.d.ts new file mode 100644 index 0000000..99061f8 --- /dev/null +++ b/build/faceFeatureExtractor/index.d.ts @@ -0,0 +1,2 @@ +export * from './FaceFeatureExtractor'; +export * from './TinyFaceFeatureExtractor'; diff --git a/build/faceFeatureExtractor/index.js b/build/faceFeatureExtractor/index.js new file mode 100644 index 0000000..149df2a --- /dev/null +++ b/build/faceFeatureExtractor/index.js @@ -0,0 +1,3 @@ +export * from './FaceFeatureExtractor'; +export * from './TinyFaceFeatureExtractor'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/faceFeatureExtractor/index.js.map b/build/faceFeatureExtractor/index.js.map new file mode 100644 index 0000000..3f6f866 --- /dev/null +++ b/build/faceFeatureExtractor/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceFeatureExtractor/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC"} \ No newline at end of file diff --git a/build/faceFeatureExtractor/loadParamsFactory.d.ts b/build/faceFeatureExtractor/loadParamsFactory.d.ts new file mode 100644 index 0000000..4e89f77 --- /dev/null +++ b/build/faceFeatureExtractor/loadParamsFactory.d.ts @@ -0,0 +1,6 @@ +import { ParamMapping } from '../common'; +import { DenseBlock3Params, DenseBlock4Params } from './types'; +export declare function loadParamsFactory(weightMap: any, paramMappings: ParamMapping[]): { + extractDenseBlock3Params: (prefix: string, isFirstLayer?: boolean) => DenseBlock3Params; + extractDenseBlock4Params: (prefix: string, isFirstLayer?: boolean) => DenseBlock4Params; +}; diff --git a/build/faceFeatureExtractor/loadParamsFactory.js b/build/faceFeatureExtractor/loadParamsFactory.js new file mode 100644 index 0000000..06706eb --- /dev/null +++ b/build/faceFeatureExtractor/loadParamsFactory.js @@ -0,0 +1,29 @@ +import { extractWeightEntryFactory, loadSeparableConvParamsFactory } from '../common'; +import { loadConvParamsFactory } from '../common/loadConvParamsFactory'; +export function loadParamsFactory(weightMap, paramMappings) { + const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); + const extractConvParams = loadConvParamsFactory(extractWeightEntry); + const extractSeparableConvParams = loadSeparableConvParamsFactory(extractWeightEntry); + function extractDenseBlock3Params(prefix, isFirstLayer = false) { + const conv0 = isFirstLayer + ? extractConvParams(`${prefix}/conv0`) + : extractSeparableConvParams(`${prefix}/conv0`); + const conv1 = extractSeparableConvParams(`${prefix}/conv1`); + const conv2 = extractSeparableConvParams(`${prefix}/conv2`); + return { conv0, conv1, conv2 }; + } + function extractDenseBlock4Params(prefix, isFirstLayer = false) { + const conv0 = isFirstLayer + ? extractConvParams(`${prefix}/conv0`) + : extractSeparableConvParams(`${prefix}/conv0`); + const conv1 = extractSeparableConvParams(`${prefix}/conv1`); + const conv2 = extractSeparableConvParams(`${prefix}/conv2`); + const conv3 = extractSeparableConvParams(`${prefix}/conv3`); + return { conv0, conv1, conv2, conv3 }; + } + return { + extractDenseBlock3Params, + extractDenseBlock4Params + }; +} +//# sourceMappingURL=loadParamsFactory.js.map \ No newline at end of file diff --git a/build/faceFeatureExtractor/loadParamsFactory.js.map b/build/faceFeatureExtractor/loadParamsFactory.js.map new file mode 100644 index 0000000..1959176 --- /dev/null +++ b/build/faceFeatureExtractor/loadParamsFactory.js.map @@ -0,0 +1 @@ +{"version":3,"file":"loadParamsFactory.js","sourceRoot":"","sources":["../../src/faceFeatureExtractor/loadParamsFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,8BAA8B,EAAgB,MAAM,WAAW,CAAC;AACpG,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAGxE,MAAM,UAAU,iBAAiB,CAAC,SAAc,EAAE,aAA6B;IAE7E,MAAM,kBAAkB,GAAG,yBAAyB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAE9E,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,kBAAkB,CAAC,CAAA;IACnE,MAAM,0BAA0B,GAAG,8BAA8B,CAAC,kBAAkB,CAAC,CAAA;IAErF,SAAS,wBAAwB,CAAC,MAAc,EAAE,eAAwB,KAAK;QAC7E,MAAM,KAAK,GAAG,YAAY;YACxB,CAAC,CAAC,iBAAiB,CAAC,GAAG,MAAM,QAAQ,CAAC;YACtC,CAAC,CAAC,0BAA0B,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAA;QACjD,MAAM,KAAK,GAAG,0BAA0B,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAA;QAC3D,MAAM,KAAK,GAAG,0BAA0B,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAA;QAE3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IAChC,CAAC;IAED,SAAS,wBAAwB,CAAC,MAAc,EAAE,eAAwB,KAAK;QAC7E,MAAM,KAAK,GAAG,YAAY;YACxB,CAAC,CAAC,iBAAiB,CAAC,GAAG,MAAM,QAAQ,CAAC;YACtC,CAAC,CAAC,0BAA0B,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAA;QACjD,MAAM,KAAK,GAAG,0BAA0B,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAA;QAC3D,MAAM,KAAK,GAAG,0BAA0B,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAA;QAC3D,MAAM,KAAK,GAAG,0BAA0B,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAA;QAE3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IACvC,CAAC;IAED,OAAO;QACL,wBAAwB;QACxB,wBAAwB;KACzB,CAAA;AACH,CAAC"} \ No newline at end of file diff --git a/build/faceFeatureExtractor/types.d.ts b/build/faceFeatureExtractor/types.d.ts new file mode 100644 index 0000000..bec1515 --- /dev/null +++ b/build/faceFeatureExtractor/types.d.ts @@ -0,0 +1,40 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { NetInput, TNetInput } from '..'; +import { ConvParams, SeparableConvParams } from '../common'; +import { NeuralNetwork } from '../NeuralNetwork'; +export declare type ConvWithBatchNormParams = BatchNormParams & { + filter: tf.Tensor4D; +}; +export declare type BatchNormParams = { + mean: tf.Tensor1D; + variance: tf.Tensor1D; + scale: tf.Tensor1D; + offset: tf.Tensor1D; +}; +export declare type SeparableConvWithBatchNormParams = { + depthwise: ConvWithBatchNormParams; + pointwise: ConvWithBatchNormParams; +}; +export declare type DenseBlock3Params = { + conv0: SeparableConvParams | ConvParams; + conv1: SeparableConvParams; + conv2: SeparableConvParams; +}; +export declare type DenseBlock4Params = DenseBlock3Params & { + conv3: SeparableConvParams; +}; +export declare type TinyFaceFeatureExtractorParams = { + dense0: DenseBlock3Params; + dense1: DenseBlock3Params; + dense2: DenseBlock3Params; +}; +export declare type FaceFeatureExtractorParams = { + dense0: DenseBlock4Params; + dense1: DenseBlock4Params; + dense2: DenseBlock4Params; + dense3: DenseBlock4Params; +}; +export interface IFaceFeatureExtractor extends NeuralNetwork { + forwardInput(input: NetInput): tf.Tensor4D; + forward(input: TNetInput): Promise; +} diff --git a/build/faceFeatureExtractor/types.js b/build/faceFeatureExtractor/types.js new file mode 100644 index 0000000..5b2306a --- /dev/null +++ b/build/faceFeatureExtractor/types.js @@ -0,0 +1 @@ +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/build/faceFeatureExtractor/types.js.map b/build/faceFeatureExtractor/types.js.map new file mode 100644 index 0000000..94f9edb --- /dev/null +++ b/build/faceFeatureExtractor/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/faceFeatureExtractor/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/faceLandmarkNet/FaceLandmark68Net.d.ts b/build/faceLandmarkNet/FaceLandmark68Net.d.ts new file mode 100644 index 0000000..ba213c9 --- /dev/null +++ b/build/faceLandmarkNet/FaceLandmark68Net.d.ts @@ -0,0 +1,8 @@ +import { FaceFeatureExtractor } from '../faceFeatureExtractor/FaceFeatureExtractor'; +import { FaceFeatureExtractorParams } from '../faceFeatureExtractor/types'; +import { FaceLandmark68NetBase } from './FaceLandmark68NetBase'; +export declare class FaceLandmark68Net extends FaceLandmark68NetBase { + constructor(faceFeatureExtractor?: FaceFeatureExtractor); + protected getDefaultModelName(): string; + protected getClassifierChannelsIn(): number; +} diff --git a/build/faceLandmarkNet/FaceLandmark68Net.js b/build/faceLandmarkNet/FaceLandmark68Net.js new file mode 100644 index 0000000..6d4c73d --- /dev/null +++ b/build/faceLandmarkNet/FaceLandmark68Net.js @@ -0,0 +1,14 @@ +import { FaceFeatureExtractor } from '../faceFeatureExtractor/FaceFeatureExtractor'; +import { FaceLandmark68NetBase } from './FaceLandmark68NetBase'; +export class FaceLandmark68Net extends FaceLandmark68NetBase { + constructor(faceFeatureExtractor = new FaceFeatureExtractor()) { + super('FaceLandmark68Net', faceFeatureExtractor); + } + getDefaultModelName() { + return 'face_landmark_68_model'; + } + getClassifierChannelsIn() { + return 256; + } +} +//# sourceMappingURL=FaceLandmark68Net.js.map \ No newline at end of file diff --git a/build/faceLandmarkNet/FaceLandmark68Net.js.map b/build/faceLandmarkNet/FaceLandmark68Net.js.map new file mode 100644 index 0000000..7c16a36 --- /dev/null +++ b/build/faceLandmarkNet/FaceLandmark68Net.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FaceLandmark68Net.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/FaceLandmark68Net.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AAEpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,OAAO,iBAAkB,SAAQ,qBAAiD;IAEtF,YAAY,uBAA6C,IAAI,oBAAoB,EAAE;QACjF,KAAK,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,CAAA;IAClD,CAAC;IAES,mBAAmB;QAC3B,OAAO,wBAAwB,CAAA;IACjC,CAAC;IAES,uBAAuB;QAC/B,OAAO,GAAG,CAAA;IACZ,CAAC;CACF"} \ No newline at end of file diff --git a/build/faceLandmarkNet/FaceLandmark68NetBase.d.ts b/build/faceLandmarkNet/FaceLandmark68NetBase.d.ts new file mode 100644 index 0000000..d4f4b31 --- /dev/null +++ b/build/faceLandmarkNet/FaceLandmark68NetBase.d.ts @@ -0,0 +1,13 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { IDimensions } from '../classes'; +import { FaceLandmarks68 } from '../classes/FaceLandmarks68'; +import { NetInput, TNetInput } from '../dom'; +import { FaceFeatureExtractorParams, TinyFaceFeatureExtractorParams } from '../faceFeatureExtractor/types'; +import { FaceProcessor } from '../faceProcessor/FaceProcessor'; +export declare abstract class FaceLandmark68NetBase extends FaceProcessor { + postProcess(output: tf.Tensor2D, inputSize: number, originalDimensions: IDimensions[]): tf.Tensor2D; + forwardInput(input: NetInput): tf.Tensor2D; + forward(input: TNetInput): Promise; + detectLandmarks(input: TNetInput): Promise; + protected getClassifierChannelsOut(): number; +} diff --git a/build/faceLandmarkNet/FaceLandmark68NetBase.js b/build/faceLandmarkNet/FaceLandmark68NetBase.js new file mode 100644 index 0000000..5801a8e --- /dev/null +++ b/build/faceLandmarkNet/FaceLandmark68NetBase.js @@ -0,0 +1,65 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { Point } from '../classes'; +import { FaceLandmarks68 } from '../classes/FaceLandmarks68'; +import { toNetInput } from '../dom'; +import { FaceProcessor } from '../faceProcessor/FaceProcessor'; +import { isEven } from '../utils'; +export class FaceLandmark68NetBase extends FaceProcessor { + postProcess(output, inputSize, originalDimensions) { + const inputDimensions = originalDimensions.map(({ width, height }) => { + const scale = inputSize / Math.max(height, width); + return { + width: width * scale, + height: height * scale + }; + }); + const batchSize = inputDimensions.length; + return tf.tidy(() => { + const createInterleavedTensor = (fillX, fillY) => tf.stack([ + tf.fill([68], fillX), + tf.fill([68], fillY) + ], 1).as2D(1, 136).as1D(); + const getPadding = (batchIdx, cond) => { + const { width, height } = inputDimensions[batchIdx]; + return cond(width, height) ? Math.abs(width - height) / 2 : 0; + }; + const getPaddingX = (batchIdx) => getPadding(batchIdx, (w, h) => w < h); + const getPaddingY = (batchIdx) => getPadding(batchIdx, (w, h) => h < w); + const landmarkTensors = output + .mul(tf.fill([batchSize, 136], inputSize)) + .sub(tf.stack(Array.from(Array(batchSize), (_, batchIdx) => createInterleavedTensor(getPaddingX(batchIdx), getPaddingY(batchIdx))))) + .div(tf.stack(Array.from(Array(batchSize), (_, batchIdx) => createInterleavedTensor(inputDimensions[batchIdx].width, inputDimensions[batchIdx].height)))); + return landmarkTensors; + }); + } + forwardInput(input) { + return tf.tidy(() => { + const out = this.runNet(input); + return this.postProcess(out, input.inputSize, input.inputDimensions.map(([height, width]) => ({ height, width }))); + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + async detectLandmarks(input) { + const netInput = await toNetInput(input); + const landmarkTensors = tf.tidy(() => tf.unstack(this.forwardInput(netInput))); + const landmarksForBatch = await Promise.all(landmarkTensors.map(async (landmarkTensor, batchIdx) => { + const landmarksArray = Array.from(await landmarkTensor.data()); + const xCoords = landmarksArray.filter((_, i) => isEven(i)); + const yCoords = landmarksArray.filter((_, i) => !isEven(i)); + return new FaceLandmarks68(Array(68).fill(0).map((_, i) => new Point(xCoords[i], yCoords[i])), { + height: netInput.getInputHeight(batchIdx), + width: netInput.getInputWidth(batchIdx), + }); + })); + landmarkTensors.forEach(t => t.dispose()); + return netInput.isBatchInput + ? landmarksForBatch + : landmarksForBatch[0]; + } + getClassifierChannelsOut() { + return 136; + } +} +//# sourceMappingURL=FaceLandmark68NetBase.js.map \ No newline at end of file diff --git a/build/faceLandmarkNet/FaceLandmark68NetBase.js.map b/build/faceLandmarkNet/FaceLandmark68NetBase.js.map new file mode 100644 index 0000000..2fae2ed --- /dev/null +++ b/build/faceLandmarkNet/FaceLandmark68NetBase.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FaceLandmark68NetBase.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/FaceLandmark68NetBase.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/faceLandmarkNet/FaceLandmark68TinyNet.d.ts b/build/faceLandmarkNet/FaceLandmark68TinyNet.d.ts new file mode 100644 index 0000000..5811187 --- /dev/null +++ b/build/faceLandmarkNet/FaceLandmark68TinyNet.d.ts @@ -0,0 +1,8 @@ +import { TinyFaceFeatureExtractor } from '../faceFeatureExtractor/TinyFaceFeatureExtractor'; +import { TinyFaceFeatureExtractorParams } from '../faceFeatureExtractor/types'; +import { FaceLandmark68NetBase } from './FaceLandmark68NetBase'; +export declare class FaceLandmark68TinyNet extends FaceLandmark68NetBase { + constructor(faceFeatureExtractor?: TinyFaceFeatureExtractor); + protected getDefaultModelName(): string; + protected getClassifierChannelsIn(): number; +} diff --git a/build/faceLandmarkNet/FaceLandmark68TinyNet.js b/build/faceLandmarkNet/FaceLandmark68TinyNet.js new file mode 100644 index 0000000..5f58220 --- /dev/null +++ b/build/faceLandmarkNet/FaceLandmark68TinyNet.js @@ -0,0 +1,14 @@ +import { TinyFaceFeatureExtractor } from '../faceFeatureExtractor/TinyFaceFeatureExtractor'; +import { FaceLandmark68NetBase } from './FaceLandmark68NetBase'; +export class FaceLandmark68TinyNet extends FaceLandmark68NetBase { + constructor(faceFeatureExtractor = new TinyFaceFeatureExtractor()) { + super('FaceLandmark68TinyNet', faceFeatureExtractor); + } + getDefaultModelName() { + return 'face_landmark_68_tiny_model'; + } + getClassifierChannelsIn() { + return 128; + } +} +//# sourceMappingURL=FaceLandmark68TinyNet.js.map \ No newline at end of file diff --git a/build/faceLandmarkNet/FaceLandmark68TinyNet.js.map b/build/faceLandmarkNet/FaceLandmark68TinyNet.js.map new file mode 100644 index 0000000..a2fcdcb --- /dev/null +++ b/build/faceLandmarkNet/FaceLandmark68TinyNet.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FaceLandmark68TinyNet.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/FaceLandmark68TinyNet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kDAAkD,CAAC;AAE5F,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,OAAO,qBAAsB,SAAQ,qBAAqD;IAE9F,YAAY,uBAAiD,IAAI,wBAAwB,EAAE;QACzF,KAAK,CAAC,uBAAuB,EAAE,oBAAoB,CAAC,CAAA;IACtD,CAAC;IAES,mBAAmB;QAC3B,OAAO,6BAA6B,CAAA;IACtC,CAAC;IAES,uBAAuB;QAC/B,OAAO,GAAG,CAAA;IACZ,CAAC;CACF"} \ No newline at end of file diff --git a/build/faceLandmarkNet/index.d.ts b/build/faceLandmarkNet/index.d.ts new file mode 100644 index 0000000..b49c3e8 --- /dev/null +++ b/build/faceLandmarkNet/index.d.ts @@ -0,0 +1,5 @@ +import { FaceLandmark68Net } from './FaceLandmark68Net'; +export * from './FaceLandmark68Net'; +export * from './FaceLandmark68TinyNet'; +export declare class FaceLandmarkNet extends FaceLandmark68Net { +} diff --git a/build/faceLandmarkNet/index.js b/build/faceLandmarkNet/index.js new file mode 100644 index 0000000..154ed93 --- /dev/null +++ b/build/faceLandmarkNet/index.js @@ -0,0 +1,6 @@ +import { FaceLandmark68Net } from './FaceLandmark68Net'; +export * from './FaceLandmark68Net'; +export * from './FaceLandmark68TinyNet'; +export class FaceLandmarkNet extends FaceLandmark68Net { +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/faceLandmarkNet/index.js.map b/build/faceLandmarkNet/index.js.map new file mode 100644 index 0000000..d957c37 --- /dev/null +++ b/build/faceLandmarkNet/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AAExC,MAAM,OAAO,eAAgB,SAAQ,iBAAiB;CAAG"} \ No newline at end of file diff --git a/build/faceProcessor/FaceProcessor.d.ts b/build/faceProcessor/FaceProcessor.d.ts new file mode 100644 index 0000000..81dbd16 --- /dev/null +++ b/build/faceProcessor/FaceProcessor.d.ts @@ -0,0 +1,28 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { NetInput } from '../dom'; +import { FaceFeatureExtractorParams, IFaceFeatureExtractor, TinyFaceFeatureExtractorParams } from '../faceFeatureExtractor/types'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { NetParams } from './types'; +export declare abstract class FaceProcessor extends NeuralNetwork { + protected _faceFeatureExtractor: IFaceFeatureExtractor; + constructor(_name: string, faceFeatureExtractor: IFaceFeatureExtractor); + get faceFeatureExtractor(): IFaceFeatureExtractor; + protected abstract getDefaultModelName(): string; + protected abstract getClassifierChannelsIn(): number; + protected abstract getClassifierChannelsOut(): number; + runNet(input: NetInput | tf.Tensor4D): tf.Tensor2D; + 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[]; + }; +} diff --git a/build/faceProcessor/FaceProcessor.js b/build/faceProcessor/FaceProcessor.js new file mode 100644 index 0000000..6d6fe34 --- /dev/null +++ b/build/faceProcessor/FaceProcessor.js @@ -0,0 +1,55 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { fullyConnectedLayer } from '../common/fullyConnectedLayer'; +import { NetInput } from '../dom'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { extractParams } from './extractParams'; +import { extractParamsFromWeigthMap } from './extractParamsFromWeigthMap'; +import { seperateWeightMaps } from './util'; +export class FaceProcessor extends NeuralNetwork { + constructor(_name, faceFeatureExtractor) { + super(_name); + 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; + return fullyConnectedLayer(bottleneckFeatures.as2D(bottleneckFeatures.shape[0], -1), params.fc); + }); + } + 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, this.getClassifierChannelsIn(), this.getClassifierChannelsOut()); + } + extractParamsFromWeigthMap(weightMap) { + const { featureExtractorMap, classifierMap } = seperateWeightMaps(weightMap); + this.faceFeatureExtractor.loadFromWeightMap(featureExtractorMap); + return extractParamsFromWeigthMap(classifierMap); + } + extractParams(weights) { + const cIn = this.getClassifierChannelsIn(); + const cOut = this.getClassifierChannelsOut(); + const classifierWeightSize = (cOut * cIn) + cOut; + const featureExtractorWeights = weights.slice(0, weights.length - classifierWeightSize); + const classifierWeights = weights.slice(weights.length - classifierWeightSize); + this.faceFeatureExtractor.extractWeights(featureExtractorWeights); + return this.extractClassifierParams(classifierWeights); + } +} +//# sourceMappingURL=FaceProcessor.js.map \ No newline at end of file diff --git a/build/faceProcessor/FaceProcessor.js.map b/build/faceProcessor/FaceProcessor.js.map new file mode 100644 index 0000000..f4bb7f6 --- /dev/null +++ b/build/faceProcessor/FaceProcessor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FaceProcessor.js","sourceRoot":"","sources":["../../src/faceProcessor/FaceProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAMlC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAE5C,MAAM,OAAgB,aAGpB,SAAQ,aAAwB;IAIhC,YAAY,KAAa,EAAE,oBAA6D;QACtF,KAAK,CAAC,KAAK,CAAC,CAAA;QACZ,IAAI,CAAC,qBAAqB,GAAG,oBAAoB,CAAA;IACnD,CAAC;IAED,IAAW,oBAAoB;QAC7B,OAAO,IAAI,CAAC,qBAAqB,CAAA;IACnC,CAAC;IAMM,MAAM,CAAC,KAA6B;QAEzC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;QAEvB,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,gCAAgC,CAAC,CAAA;SAC/D;QAED,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;YAClB,MAAM,kBAAkB,GAAG,KAAK,YAAY,QAAQ;gBAClD,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,YAAY,CAAC,KAAK,CAAC;gBAC/C,CAAC,CAAC,KAAK,CAAA;YACT,OAAO,mBAAmB,CAAC,kBAAkB,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAA;QACjG,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,OAAO,CAAC,mBAA4B,IAAI;QAC7C,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;QACnD,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACjC,CAAC;IAEM,oBAAoB,CAAC,OAAqB;QAC/C,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAA;QACvE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,CAAC,cAAc,GAAG,aAAa,CAAA;IACrC,CAAC;IAEM,uBAAuB,CAAC,OAAqB;QAClD,OAAO,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,uBAAuB,EAAE,EAAE,IAAI,CAAC,wBAAwB,EAAE,CAAC,CAAA;IAChG,CAAC;IAES,0BAA0B,CAAC,SAA4B;QAE/D,MAAM,EAAE,mBAAmB,EAAE,aAAa,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAA;QAE5E,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAAA;QAEhE,OAAO,0BAA0B,CAAC,aAAa,CAAC,CAAA;IAClD,CAAC;IAES,aAAa,CAAC,OAAqB;QAE3C,MAAM,GAAG,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAA;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,wBAAwB,EAAE,CAAA;QAC5C,MAAM,oBAAoB,GAAG,CAAC,IAAI,GAAG,GAAG,CAAE,GAAG,IAAI,CAAA;QAEjD,MAAM,uBAAuB,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,oBAAoB,CAAC,CAAA;QACvF,MAAM,iBAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,oBAAoB,CAAC,CAAA;QAE9E,IAAI,CAAC,oBAAoB,CAAC,cAAc,CAAC,uBAAuB,CAAC,CAAA;QACjE,OAAO,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAA;IACxD,CAAC;CACF"} \ No newline at end of file diff --git a/build/faceProcessor/extractParams.d.ts b/build/faceProcessor/extractParams.d.ts new file mode 100644 index 0000000..9fc55e1 --- /dev/null +++ b/build/faceProcessor/extractParams.d.ts @@ -0,0 +1,6 @@ +import { ParamMapping } from '../common'; +import { NetParams } from './types'; +export declare function extractParams(weights: Float32Array, channelsIn: number, channelsOut: number): { + params: NetParams; + paramMappings: ParamMapping[]; +}; diff --git a/build/faceProcessor/extractParams.js b/build/faceProcessor/extractParams.js new file mode 100644 index 0000000..76eeb97 --- /dev/null +++ b/build/faceProcessor/extractParams.js @@ -0,0 +1,15 @@ +import { extractFCParamsFactory, extractWeightsFactory } from '../common'; +export function extractParams(weights, channelsIn, channelsOut) { + const paramMappings = []; + const { extractWeights, getRemainingWeights } = extractWeightsFactory(weights); + const extractFCParams = extractFCParamsFactory(extractWeights, paramMappings); + const fc = extractFCParams(channelsIn, channelsOut, 'fc'); + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { + paramMappings, + params: { fc } + }; +} +//# sourceMappingURL=extractParams.js.map \ No newline at end of file diff --git a/build/faceProcessor/extractParams.js.map b/build/faceProcessor/extractParams.js.map new file mode 100644 index 0000000..6807039 --- /dev/null +++ b/build/faceProcessor/extractParams.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParams.js","sourceRoot":"","sources":["../../src/faceProcessor/extractParams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAgB,MAAM,WAAW,CAAC;AAGxF,MAAM,UAAU,aAAa,CAAC,OAAqB,EAAE,UAAkB,EAAE,WAAmB;IAE1F,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,EAAE,GAAG,eAAe,CAAC,UAAU,EAAE,WAAW,EAAE,IAAI,CAAC,CAAA;IAEzD,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;KACf,CAAA;AACH,CAAC"} \ No newline at end of file diff --git a/build/faceProcessor/extractParamsFromWeigthMap.d.ts b/build/faceProcessor/extractParamsFromWeigthMap.d.ts new file mode 100644 index 0000000..82627ad --- /dev/null +++ b/build/faceProcessor/extractParamsFromWeigthMap.d.ts @@ -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[]; +}; diff --git a/build/faceProcessor/extractParamsFromWeigthMap.js b/build/faceProcessor/extractParamsFromWeigthMap.js new file mode 100644 index 0000000..67c620e --- /dev/null +++ b/build/faceProcessor/extractParamsFromWeigthMap.js @@ -0,0 +1,16 @@ +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: extractFcParams('fc') + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} +//# sourceMappingURL=extractParamsFromWeigthMap.js.map \ No newline at end of file diff --git a/build/faceProcessor/extractParamsFromWeigthMap.js.map b/build/faceProcessor/extractParamsFromWeigthMap.js.map new file mode 100644 index 0000000..c04cc81 --- /dev/null +++ b/build/faceProcessor/extractParamsFromWeigthMap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParamsFromWeigthMap.js","sourceRoot":"","sources":["../../src/faceProcessor/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,eAAe,CAAC,IAAI,CAAC;KAC1B,CAAA;IAED,0BAA0B,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAEpD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAA;AAClC,CAAC"} \ No newline at end of file diff --git a/build/faceProcessor/index.d.ts b/build/faceProcessor/index.d.ts new file mode 100644 index 0000000..9e98e7d --- /dev/null +++ b/build/faceProcessor/index.d.ts @@ -0,0 +1 @@ +export * from './FaceProcessor'; diff --git a/build/faceProcessor/index.js b/build/faceProcessor/index.js new file mode 100644 index 0000000..43ae5c6 --- /dev/null +++ b/build/faceProcessor/index.js @@ -0,0 +1,2 @@ +export * from './FaceProcessor'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/faceProcessor/index.js.map b/build/faceProcessor/index.js.map new file mode 100644 index 0000000..0ea0f85 --- /dev/null +++ b/build/faceProcessor/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceProcessor/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"} \ No newline at end of file diff --git a/build/faceProcessor/types.d.ts b/build/faceProcessor/types.d.ts new file mode 100644 index 0000000..2e6085a --- /dev/null +++ b/build/faceProcessor/types.d.ts @@ -0,0 +1,4 @@ +import { FCParams } from '../common'; +export declare type NetParams = { + fc: FCParams; +}; diff --git a/build/faceProcessor/types.js b/build/faceProcessor/types.js new file mode 100644 index 0000000..5b2306a --- /dev/null +++ b/build/faceProcessor/types.js @@ -0,0 +1 @@ +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/build/faceProcessor/types.js.map b/build/faceProcessor/types.js.map new file mode 100644 index 0000000..86dee21 --- /dev/null +++ b/build/faceProcessor/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/faceProcessor/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/faceProcessor/util.d.ts b/build/faceProcessor/util.d.ts new file mode 100644 index 0000000..e28fedc --- /dev/null +++ b/build/faceProcessor/util.d.ts @@ -0,0 +1,5 @@ +import * as tf from '@tensorflow/tfjs-core'; +export declare function seperateWeightMaps(weightMap: tf.NamedTensorMap): { + featureExtractorMap: tf.NamedTensorMap; + classifierMap: tf.NamedTensorMap; +}; diff --git a/build/faceProcessor/util.js b/build/faceProcessor/util.js new file mode 100644 index 0000000..f400d03 --- /dev/null +++ b/build/faceProcessor/util.js @@ -0,0 +1,10 @@ +export function seperateWeightMaps(weightMap) { + const featureExtractorMap = {}; + const classifierMap = {}; + Object.keys(weightMap).forEach(key => { + const map = key.startsWith('fc') ? classifierMap : featureExtractorMap; + map[key] = weightMap[key]; + }); + return { featureExtractorMap, classifierMap }; +} +//# sourceMappingURL=util.js.map \ No newline at end of file diff --git a/build/faceProcessor/util.js.map b/build/faceProcessor/util.js.map new file mode 100644 index 0000000..282c9d7 --- /dev/null +++ b/build/faceProcessor/util.js.map @@ -0,0 +1 @@ +{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/faceProcessor/util.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,kBAAkB,CAAC,SAA4B;IAE7D,MAAM,mBAAmB,GAAsB,EAAE,CAAA;IACjD,MAAM,aAAa,GAAsB,EAAE,CAAA;IAE3C,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QACnC,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,mBAAmB,CAAA;QACtE,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;IAEF,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,CAAA;AAE/C,CAAC"} \ No newline at end of file diff --git a/build/faceRecognitionNet/FaceRecognitionNet.d.ts b/build/faceRecognitionNet/FaceRecognitionNet.d.ts new file mode 100644 index 0000000..b794c56 --- /dev/null +++ b/build/faceRecognitionNet/FaceRecognitionNet.d.ts @@ -0,0 +1,19 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { NetInput, TNetInput } from '../dom'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { NetParams } from './types'; +export declare class FaceRecognitionNet extends NeuralNetwork { + constructor(); + forwardInput(input: NetInput): tf.Tensor2D; + forward(input: TNetInput): Promise; + computeFaceDescriptor(input: TNetInput): Promise; + protected getDefaultModelName(): string; + protected extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap): { + params: NetParams; + paramMappings: import("../common").ParamMapping[]; + }; + protected extractParams(weights: Float32Array): { + params: NetParams; + paramMappings: import("../common").ParamMapping[]; + }; +} diff --git a/build/faceRecognitionNet/FaceRecognitionNet.js b/build/faceRecognitionNet/FaceRecognitionNet.js new file mode 100644 index 0000000..f283492 --- /dev/null +++ b/build/faceRecognitionNet/FaceRecognitionNet.js @@ -0,0 +1,65 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { toNetInput } from '../dom'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { normalize } from '../ops'; +import { convDown } from './convLayer'; +import { extractParams } from './extractParams'; +import { extractParamsFromWeigthMap } from './extractParamsFromWeigthMap'; +import { residual, residualDown } from './residualLayer'; +export class FaceRecognitionNet extends NeuralNetwork { + constructor() { + super('FaceRecognitionNet'); + } + forwardInput(input) { + const { params } = this; + if (!params) { + throw new Error('FaceRecognitionNet - load model before inference'); + } + return tf.tidy(() => { + const batchTensor = input.toBatchTensor(150, true).toFloat(); + const meanRgb = [122.782, 117.001, 104.298]; + const normalized = normalize(batchTensor, meanRgb).div(tf.scalar(256)); + let out = convDown(normalized, params.conv32_down); + out = tf.maxPool(out, 3, 2, 'valid'); + out = residual(out, params.conv32_1); + out = residual(out, params.conv32_2); + out = residual(out, params.conv32_3); + out = residualDown(out, params.conv64_down); + out = residual(out, params.conv64_1); + out = residual(out, params.conv64_2); + out = residual(out, params.conv64_3); + out = residualDown(out, params.conv128_down); + out = residual(out, params.conv128_1); + out = residual(out, params.conv128_2); + out = residualDown(out, params.conv256_down); + out = residual(out, params.conv256_1); + out = residual(out, params.conv256_2); + out = residualDown(out, params.conv256_down_out); + const globalAvg = out.mean([1, 2]); + const fullyConnected = tf.matMul(globalAvg, params.fc); + return fullyConnected; + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + async computeFaceDescriptor(input) { + const netInput = await toNetInput(input); + const faceDescriptorTensors = tf.tidy(() => tf.unstack(this.forwardInput(netInput))); + const faceDescriptorsForBatch = await Promise.all(faceDescriptorTensors.map(t => t.data())); + faceDescriptorTensors.forEach(t => t.dispose()); + return netInput.isBatchInput + ? faceDescriptorsForBatch + : faceDescriptorsForBatch[0]; + } + getDefaultModelName() { + return 'face_recognition_model'; + } + extractParamsFromWeigthMap(weightMap) { + return extractParamsFromWeigthMap(weightMap); + } + extractParams(weights) { + return extractParams(weights); + } +} +//# sourceMappingURL=FaceRecognitionNet.js.map \ No newline at end of file diff --git a/build/faceRecognitionNet/FaceRecognitionNet.js.map b/build/faceRecognitionNet/FaceRecognitionNet.js.map new file mode 100644 index 0000000..c6af66a --- /dev/null +++ b/build/faceRecognitionNet/FaceRecognitionNet.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FaceRecognitionNet.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/FaceRecognitionNet.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/faceRecognitionNet/convLayer.d.ts b/build/faceRecognitionNet/convLayer.d.ts new file mode 100644 index 0000000..1640a10 --- /dev/null +++ b/build/faceRecognitionNet/convLayer.d.ts @@ -0,0 +1,5 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { ConvLayerParams } from './types'; +export declare function conv(x: tf.Tensor4D, params: ConvLayerParams): tf.Tensor4D; +export declare function convNoRelu(x: tf.Tensor4D, params: ConvLayerParams): tf.Tensor4D; +export declare function convDown(x: tf.Tensor4D, params: ConvLayerParams): tf.Tensor4D; diff --git a/build/faceRecognitionNet/convLayer.js b/build/faceRecognitionNet/convLayer.js new file mode 100644 index 0000000..9aa5ca9 --- /dev/null +++ b/build/faceRecognitionNet/convLayer.js @@ -0,0 +1,19 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { scale } from './scaleLayer'; +function convLayer(x, params, strides, withRelu, padding = 'same') { + const { filters, bias } = params.conv; + let out = tf.conv2d(x, filters, strides, padding); + out = tf.add(out, bias); + out = scale(out, params.scale); + return withRelu ? tf.relu(out) : out; +} +export function conv(x, params) { + return convLayer(x, params, [1, 1], true); +} +export function convNoRelu(x, params) { + return convLayer(x, params, [1, 1], false); +} +export function convDown(x, params) { + return convLayer(x, params, [2, 2], true, 'valid'); +} +//# sourceMappingURL=convLayer.js.map \ No newline at end of file diff --git a/build/faceRecognitionNet/convLayer.js.map b/build/faceRecognitionNet/convLayer.js.map new file mode 100644 index 0000000..676f31e --- /dev/null +++ b/build/faceRecognitionNet/convLayer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"convLayer.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/convLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAIrC,SAAS,SAAS,CAChB,CAAc,EACd,MAAuB,EACvB,OAAyB,EACzB,QAAiB,EACjB,UAA4B,MAAM;IAElC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,IAAI,CAAA;IAErC,IAAI,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACjD,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACvB,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;IAC9B,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,CAAc,EAAE,MAAuB;IAC1D,OAAO,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;AAC3C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAc,EAAE,MAAuB;IAChE,OAAO,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,CAAc,EAAE,MAAuB;IAC9D,OAAO,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;AACpD,CAAC"} \ No newline at end of file diff --git a/build/faceRecognitionNet/extractParams.d.ts b/build/faceRecognitionNet/extractParams.d.ts new file mode 100644 index 0000000..f4e4b30 --- /dev/null +++ b/build/faceRecognitionNet/extractParams.d.ts @@ -0,0 +1,6 @@ +import { ParamMapping } from '../common'; +import { NetParams } from './types'; +export declare function extractParams(weights: Float32Array): { + params: NetParams; + paramMappings: ParamMapping[]; +}; diff --git a/build/faceRecognitionNet/extractParams.js b/build/faceRecognitionNet/extractParams.js new file mode 100644 index 0000000..01c5701 --- /dev/null +++ b/build/faceRecognitionNet/extractParams.js @@ -0,0 +1,87 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { extractWeightsFactory } from '../common'; +import { isFloat } from '../utils'; +function extractorsFactory(extractWeights, paramMappings) { + function extractFilterValues(numFilterValues, numFilters, filterSize) { + const weights = extractWeights(numFilterValues); + const depth = weights.length / (numFilters * filterSize * filterSize); + if (isFloat(depth)) { + throw new Error(`depth has to be an integer: ${depth}, weights.length: ${weights.length}, numFilters: ${numFilters}, filterSize: ${filterSize}`); + } + return tf.tidy(() => tf.transpose(tf.tensor4d(weights, [numFilters, depth, filterSize, filterSize]), [2, 3, 1, 0])); + } + function extractConvParams(numFilterValues, numFilters, filterSize, mappedPrefix) { + const filters = extractFilterValues(numFilterValues, numFilters, filterSize); + const bias = tf.tensor1d(extractWeights(numFilters)); + paramMappings.push({ paramPath: `${mappedPrefix}/filters` }, { paramPath: `${mappedPrefix}/bias` }); + return { filters, bias }; + } + function extractScaleLayerParams(numWeights, mappedPrefix) { + const weights = tf.tensor1d(extractWeights(numWeights)); + const biases = tf.tensor1d(extractWeights(numWeights)); + paramMappings.push({ paramPath: `${mappedPrefix}/weights` }, { paramPath: `${mappedPrefix}/biases` }); + return { + weights, + biases + }; + } + function extractConvLayerParams(numFilterValues, numFilters, filterSize, mappedPrefix) { + const conv = extractConvParams(numFilterValues, numFilters, filterSize, `${mappedPrefix}/conv`); + const scale = extractScaleLayerParams(numFilters, `${mappedPrefix}/scale`); + return { conv, scale }; + } + function extractResidualLayerParams(numFilterValues, numFilters, filterSize, mappedPrefix, isDown = false) { + const conv1 = extractConvLayerParams((isDown ? 0.5 : 1) * numFilterValues, numFilters, filterSize, `${mappedPrefix}/conv1`); + const conv2 = extractConvLayerParams(numFilterValues, numFilters, filterSize, `${mappedPrefix}/conv2`); + return { conv1, conv2 }; + } + return { + extractConvLayerParams, + extractResidualLayerParams + }; +} +export function extractParams(weights) { + const { extractWeights, getRemainingWeights } = extractWeightsFactory(weights); + const paramMappings = []; + const { extractConvLayerParams, extractResidualLayerParams } = extractorsFactory(extractWeights, paramMappings); + const conv32_down = extractConvLayerParams(4704, 32, 7, 'conv32_down'); + const conv32_1 = extractResidualLayerParams(9216, 32, 3, 'conv32_1'); + const conv32_2 = extractResidualLayerParams(9216, 32, 3, 'conv32_2'); + const conv32_3 = extractResidualLayerParams(9216, 32, 3, 'conv32_3'); + const conv64_down = extractResidualLayerParams(36864, 64, 3, 'conv64_down', true); + const conv64_1 = extractResidualLayerParams(36864, 64, 3, 'conv64_1'); + const conv64_2 = extractResidualLayerParams(36864, 64, 3, 'conv64_2'); + const conv64_3 = extractResidualLayerParams(36864, 64, 3, 'conv64_3'); + const conv128_down = extractResidualLayerParams(147456, 128, 3, 'conv128_down', true); + const conv128_1 = extractResidualLayerParams(147456, 128, 3, 'conv128_1'); + const conv128_2 = extractResidualLayerParams(147456, 128, 3, 'conv128_2'); + const conv256_down = extractResidualLayerParams(589824, 256, 3, 'conv256_down', true); + const conv256_1 = extractResidualLayerParams(589824, 256, 3, 'conv256_1'); + const conv256_2 = extractResidualLayerParams(589824, 256, 3, 'conv256_2'); + const conv256_down_out = extractResidualLayerParams(589824, 256, 3, 'conv256_down_out'); + const fc = tf.tidy(() => tf.transpose(tf.tensor2d(extractWeights(256 * 128), [128, 256]), [1, 0])); + paramMappings.push({ paramPath: `fc` }); + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + const params = { + conv32_down, + conv32_1, + conv32_2, + conv32_3, + conv64_down, + conv64_1, + conv64_2, + conv64_3, + conv128_down, + conv128_1, + conv128_2, + conv256_down, + conv256_1, + conv256_2, + conv256_down_out, + fc + }; + return { params, paramMappings }; +} +//# sourceMappingURL=extractParams.js.map \ No newline at end of file diff --git a/build/faceRecognitionNet/extractParams.js.map b/build/faceRecognitionNet/extractParams.js.map new file mode 100644 index 0000000..9fd7b72 --- /dev/null +++ b/build/faceRecognitionNet/extractParams.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParams.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/extractParams.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/faceRecognitionNet/extractParamsFromWeigthMap.d.ts b/build/faceRecognitionNet/extractParamsFromWeigthMap.d.ts new file mode 100644 index 0000000..82627ad --- /dev/null +++ b/build/faceRecognitionNet/extractParamsFromWeigthMap.d.ts @@ -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[]; +}; diff --git a/build/faceRecognitionNet/extractParamsFromWeigthMap.js b/build/faceRecognitionNet/extractParamsFromWeigthMap.js new file mode 100644 index 0000000..8394d3d --- /dev/null +++ b/build/faceRecognitionNet/extractParamsFromWeigthMap.js @@ -0,0 +1,71 @@ +import { disposeUnusedWeightTensors, extractWeightEntryFactory } from '../common'; +import { isTensor2D } from '../utils'; +function extractorsFactory(weightMap, paramMappings) { + const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); + function extractScaleLayerParams(prefix) { + const weights = extractWeightEntry(`${prefix}/scale/weights`, 1); + const biases = extractWeightEntry(`${prefix}/scale/biases`, 1); + return { weights, biases }; + } + function extractConvLayerParams(prefix) { + const filters = extractWeightEntry(`${prefix}/conv/filters`, 4); + const bias = extractWeightEntry(`${prefix}/conv/bias`, 1); + const scale = extractScaleLayerParams(prefix); + return { conv: { filters, bias }, scale }; + } + function extractResidualLayerParams(prefix) { + return { + conv1: extractConvLayerParams(`${prefix}/conv1`), + conv2: extractConvLayerParams(`${prefix}/conv2`) + }; + } + return { + extractConvLayerParams, + extractResidualLayerParams + }; +} +export function extractParamsFromWeigthMap(weightMap) { + const paramMappings = []; + const { extractConvLayerParams, extractResidualLayerParams } = extractorsFactory(weightMap, paramMappings); + const conv32_down = extractConvLayerParams('conv32_down'); + const conv32_1 = extractResidualLayerParams('conv32_1'); + const conv32_2 = extractResidualLayerParams('conv32_2'); + const conv32_3 = extractResidualLayerParams('conv32_3'); + const conv64_down = extractResidualLayerParams('conv64_down'); + const conv64_1 = extractResidualLayerParams('conv64_1'); + const conv64_2 = extractResidualLayerParams('conv64_2'); + const conv64_3 = extractResidualLayerParams('conv64_3'); + const conv128_down = extractResidualLayerParams('conv128_down'); + const conv128_1 = extractResidualLayerParams('conv128_1'); + const conv128_2 = extractResidualLayerParams('conv128_2'); + const conv256_down = extractResidualLayerParams('conv256_down'); + const conv256_1 = extractResidualLayerParams('conv256_1'); + const conv256_2 = extractResidualLayerParams('conv256_2'); + const conv256_down_out = extractResidualLayerParams('conv256_down_out'); + const fc = weightMap['fc']; + paramMappings.push({ originalPath: 'fc', paramPath: 'fc' }); + if (!isTensor2D(fc)) { + throw new Error(`expected weightMap[fc] to be a Tensor2D, instead have ${fc}`); + } + const params = { + conv32_down, + conv32_1, + conv32_2, + conv32_3, + conv64_down, + conv64_1, + conv64_2, + conv64_3, + conv128_down, + conv128_1, + conv128_2, + conv256_down, + conv256_1, + conv256_2, + conv256_down_out, + fc + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} +//# sourceMappingURL=extractParamsFromWeigthMap.js.map \ No newline at end of file diff --git a/build/faceRecognitionNet/extractParamsFromWeigthMap.js.map b/build/faceRecognitionNet/extractParamsFromWeigthMap.js.map new file mode 100644 index 0000000..9c5829b --- /dev/null +++ b/build/faceRecognitionNet/extractParamsFromWeigthMap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParamsFromWeigthMap.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/extractParamsFromWeigthMap.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/faceRecognitionNet/index.d.ts b/build/faceRecognitionNet/index.d.ts new file mode 100644 index 0000000..487d6af --- /dev/null +++ b/build/faceRecognitionNet/index.d.ts @@ -0,0 +1,3 @@ +import { FaceRecognitionNet } from './FaceRecognitionNet'; +export * from './FaceRecognitionNet'; +export declare function createFaceRecognitionNet(weights: Float32Array): FaceRecognitionNet; diff --git a/build/faceRecognitionNet/index.js b/build/faceRecognitionNet/index.js new file mode 100644 index 0000000..20f2421 --- /dev/null +++ b/build/faceRecognitionNet/index.js @@ -0,0 +1,8 @@ +import { FaceRecognitionNet } from './FaceRecognitionNet'; +export * from './FaceRecognitionNet'; +export function createFaceRecognitionNet(weights) { + const net = new FaceRecognitionNet(); + net.extractWeights(weights); + return net; +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/faceRecognitionNet/index.js.map b/build/faceRecognitionNet/index.js.map new file mode 100644 index 0000000..82f4dcc --- /dev/null +++ b/build/faceRecognitionNet/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,cAAc,sBAAsB,CAAC;AAErC,MAAM,UAAU,wBAAwB,CAAC,OAAqB;IAC5D,MAAM,GAAG,GAAG,IAAI,kBAAkB,EAAE,CAAA;IACpC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IAC3B,OAAO,GAAG,CAAA;AACZ,CAAC"} \ No newline at end of file diff --git a/build/faceRecognitionNet/residualLayer.d.ts b/build/faceRecognitionNet/residualLayer.d.ts new file mode 100644 index 0000000..1656e0a --- /dev/null +++ b/build/faceRecognitionNet/residualLayer.d.ts @@ -0,0 +1,4 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { ResidualLayerParams } from './types'; +export declare function residual(x: tf.Tensor4D, params: ResidualLayerParams): tf.Tensor4D; +export declare function residualDown(x: tf.Tensor4D, params: ResidualLayerParams): tf.Tensor4D; diff --git a/build/faceRecognitionNet/residualLayer.js b/build/faceRecognitionNet/residualLayer.js new file mode 100644 index 0000000..33b411e --- /dev/null +++ b/build/faceRecognitionNet/residualLayer.js @@ -0,0 +1,32 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { conv, convDown, convNoRelu } from './convLayer'; +export function residual(x, params) { + let out = conv(x, params.conv1); + out = convNoRelu(out, params.conv2); + out = tf.add(out, x); + out = tf.relu(out); + return out; +} +export function residualDown(x, params) { + let out = convDown(x, params.conv1); + out = convNoRelu(out, params.conv2); + let pooled = tf.avgPool(x, 2, 2, 'valid'); + const zeros = tf.zeros(pooled.shape); + const isPad = pooled.shape[3] !== out.shape[3]; + const isAdjustShape = pooled.shape[1] !== out.shape[1] || pooled.shape[2] !== out.shape[2]; + if (isAdjustShape) { + const padShapeX = [...out.shape]; + padShapeX[1] = 1; + const zerosW = tf.zeros(padShapeX); + out = tf.concat([out, zerosW], 1); + const padShapeY = [...out.shape]; + padShapeY[2] = 1; + const zerosH = tf.zeros(padShapeY); + out = tf.concat([out, zerosH], 2); + } + pooled = isPad ? tf.concat([pooled, zeros], 3) : pooled; + out = tf.add(pooled, out); + out = tf.relu(out); + return out; +} +//# sourceMappingURL=residualLayer.js.map \ No newline at end of file diff --git a/build/faceRecognitionNet/residualLayer.js.map b/build/faceRecognitionNet/residualLayer.js.map new file mode 100644 index 0000000..4f805e5 --- /dev/null +++ b/build/faceRecognitionNet/residualLayer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"residualLayer.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/residualLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzD,MAAM,UAAU,QAAQ,CAAC,CAAc,EAAE,MAA2B;IAClE,IAAI,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;IAC/B,GAAG,GAAG,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;IACnC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IACpB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAClB,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAc,EAAE,MAA2B;IACtE,IAAI,GAAG,GAAG,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;IACnC,GAAG,GAAG,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;IAEnC,IAAI,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,CAAgB,CAAA;IACxD,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAa,MAAM,CAAC,KAAK,CAAC,CAAA;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC9C,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAE1F,IAAI,aAAa,EAAE;QACjB,MAAM,SAAS,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAqC,CAAA;QACpE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAChB,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAa,SAAS,CAAC,CAAA;QAC9C,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;QAEjC,MAAM,SAAS,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAqC,CAAA;QACpE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAChB,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAa,SAAS,CAAC,CAAA;QAC9C,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;KAClC;IAED,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IACvD,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAgB,CAAA;IAExC,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAClB,OAAO,GAAG,CAAA;AACZ,CAAC"} \ No newline at end of file diff --git a/build/faceRecognitionNet/scaleLayer.d.ts b/build/faceRecognitionNet/scaleLayer.d.ts new file mode 100644 index 0000000..07a866e --- /dev/null +++ b/build/faceRecognitionNet/scaleLayer.d.ts @@ -0,0 +1,3 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { ScaleLayerParams } from './types'; +export declare function scale(x: tf.Tensor4D, params: ScaleLayerParams): tf.Tensor4D; diff --git a/build/faceRecognitionNet/scaleLayer.js b/build/faceRecognitionNet/scaleLayer.js new file mode 100644 index 0000000..6c1b911 --- /dev/null +++ b/build/faceRecognitionNet/scaleLayer.js @@ -0,0 +1,5 @@ +import * as tf from '@tensorflow/tfjs-core'; +export function scale(x, params) { + return tf.add(tf.mul(x, params.weights), params.biases); +} +//# sourceMappingURL=scaleLayer.js.map \ No newline at end of file diff --git a/build/faceRecognitionNet/scaleLayer.js.map b/build/faceRecognitionNet/scaleLayer.js.map new file mode 100644 index 0000000..f40308c --- /dev/null +++ b/build/faceRecognitionNet/scaleLayer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scaleLayer.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/scaleLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAI5C,MAAM,UAAU,KAAK,CAAC,CAAc,EAAE,MAAwB;IAC5D,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;AACzD,CAAC"} \ No newline at end of file diff --git a/build/faceRecognitionNet/types.d.ts b/build/faceRecognitionNet/types.d.ts new file mode 100644 index 0000000..9b0e869 --- /dev/null +++ b/build/faceRecognitionNet/types.d.ts @@ -0,0 +1,32 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { ConvParams } from '../common'; +export declare type ScaleLayerParams = { + weights: tf.Tensor1D; + biases: tf.Tensor1D; +}; +export declare type ResidualLayerParams = { + conv1: ConvLayerParams; + conv2: ConvLayerParams; +}; +export declare type ConvLayerParams = { + conv: ConvParams; + scale: ScaleLayerParams; +}; +export declare type NetParams = { + conv32_down: ConvLayerParams; + conv32_1: ResidualLayerParams; + conv32_2: ResidualLayerParams; + conv32_3: ResidualLayerParams; + conv64_down: ResidualLayerParams; + conv64_1: ResidualLayerParams; + conv64_2: ResidualLayerParams; + conv64_3: ResidualLayerParams; + conv128_down: ResidualLayerParams; + conv128_1: ResidualLayerParams; + conv128_2: ResidualLayerParams; + conv256_down: ResidualLayerParams; + conv256_1: ResidualLayerParams; + conv256_2: ResidualLayerParams; + conv256_down_out: ResidualLayerParams; + fc: tf.Tensor2D; +}; diff --git a/build/faceRecognitionNet/types.js b/build/faceRecognitionNet/types.js new file mode 100644 index 0000000..5b2306a --- /dev/null +++ b/build/faceRecognitionNet/types.js @@ -0,0 +1 @@ +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/build/faceRecognitionNet/types.js.map b/build/faceRecognitionNet/types.js.map new file mode 100644 index 0000000..08c5615 --- /dev/null +++ b/build/faceRecognitionNet/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/faceRecognitionNet/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/factories/WithAge.d.ts b/build/factories/WithAge.d.ts new file mode 100644 index 0000000..b924852 --- /dev/null +++ b/build/factories/WithAge.d.ts @@ -0,0 +1,5 @@ +export declare type WithAge = TSource & { + age: number; +}; +export declare function isWithAge(obj: any): obj is WithAge<{}>; +export declare function extendWithAge(sourceObj: TSource, age: number): WithAge; diff --git a/build/factories/WithAge.js b/build/factories/WithAge.js new file mode 100644 index 0000000..0cf40e3 --- /dev/null +++ b/build/factories/WithAge.js @@ -0,0 +1,8 @@ +export function isWithAge(obj) { + return typeof obj['age'] === 'number'; +} +export function extendWithAge(sourceObj, age) { + const extension = { age }; + return Object.assign({}, sourceObj, extension); +} +//# sourceMappingURL=WithAge.js.map \ No newline at end of file diff --git a/build/factories/WithAge.js.map b/build/factories/WithAge.js.map new file mode 100644 index 0000000..293d432 --- /dev/null +++ b/build/factories/WithAge.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WithAge.js","sourceRoot":"","sources":["../../src/factories/WithAge.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,SAAS,CAAC,GAAQ;IAChC,OAAO,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,aAAa,CAG3B,SAAkB,EAClB,GAAW;IAGX,MAAM,SAAS,GAAG,EAAE,GAAG,EAAE,CAAA;IACzB,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;AAChD,CAAC"} \ No newline at end of file diff --git a/build/factories/WithFaceDescriptor.d.ts b/build/factories/WithFaceDescriptor.d.ts new file mode 100644 index 0000000..45175ba --- /dev/null +++ b/build/factories/WithFaceDescriptor.d.ts @@ -0,0 +1,4 @@ +export declare type WithFaceDescriptor = TSource & { + descriptor: Float32Array; +}; +export declare function extendWithFaceDescriptor(sourceObj: TSource, descriptor: Float32Array): WithFaceDescriptor; diff --git a/build/factories/WithFaceDescriptor.js b/build/factories/WithFaceDescriptor.js new file mode 100644 index 0000000..db68278 --- /dev/null +++ b/build/factories/WithFaceDescriptor.js @@ -0,0 +1,5 @@ +export function extendWithFaceDescriptor(sourceObj, descriptor) { + const extension = { descriptor }; + return Object.assign({}, sourceObj, extension); +} +//# sourceMappingURL=WithFaceDescriptor.js.map \ No newline at end of file diff --git a/build/factories/WithFaceDescriptor.js.map b/build/factories/WithFaceDescriptor.js.map new file mode 100644 index 0000000..f3184b3 --- /dev/null +++ b/build/factories/WithFaceDescriptor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WithFaceDescriptor.js","sourceRoot":"","sources":["../../src/factories/WithFaceDescriptor.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,wBAAwB,CAGtC,SAAkB,EAClB,UAAwB;IAGxB,MAAM,SAAS,GAAG,EAAE,UAAU,EAAE,CAAA;IAChC,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;AAChD,CAAC"} \ No newline at end of file diff --git a/build/factories/WithFaceDetection.d.ts b/build/factories/WithFaceDetection.d.ts new file mode 100644 index 0000000..718ea71 --- /dev/null +++ b/build/factories/WithFaceDetection.d.ts @@ -0,0 +1,6 @@ +import { FaceDetection } from '../classes/FaceDetection'; +export declare type WithFaceDetection = TSource & { + detection: FaceDetection; +}; +export declare function isWithFaceDetection(obj: any): obj is WithFaceDetection<{}>; +export declare function extendWithFaceDetection(sourceObj: TSource, detection: FaceDetection): WithFaceDetection; diff --git a/build/factories/WithFaceDetection.js b/build/factories/WithFaceDetection.js new file mode 100644 index 0000000..fc28fb5 --- /dev/null +++ b/build/factories/WithFaceDetection.js @@ -0,0 +1,9 @@ +import { FaceDetection } from '../classes/FaceDetection'; +export function isWithFaceDetection(obj) { + return obj['detection'] instanceof FaceDetection; +} +export function extendWithFaceDetection(sourceObj, detection) { + const extension = { detection }; + return Object.assign({}, sourceObj, extension); +} +//# sourceMappingURL=WithFaceDetection.js.map \ No newline at end of file diff --git a/build/factories/WithFaceDetection.js.map b/build/factories/WithFaceDetection.js.map new file mode 100644 index 0000000..bdd4e73 --- /dev/null +++ b/build/factories/WithFaceDetection.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WithFaceDetection.js","sourceRoot":"","sources":["../../src/factories/WithFaceDetection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAMzD,MAAM,UAAU,mBAAmB,CAAC,GAAQ;IAC1C,OAAO,GAAG,CAAC,WAAW,CAAC,YAAY,aAAa,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,uBAAuB,CAGrC,SAAkB,EAClB,SAAwB;IAGxB,MAAM,SAAS,GAAG,EAAE,SAAS,EAAE,CAAA;IAC/B,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;AAChD,CAAC"} \ No newline at end of file diff --git a/build/factories/WithFaceExpressions.d.ts b/build/factories/WithFaceExpressions.d.ts new file mode 100644 index 0000000..f7960b2 --- /dev/null +++ b/build/factories/WithFaceExpressions.d.ts @@ -0,0 +1,6 @@ +import { FaceExpressions } from '../faceExpressionNet/FaceExpressions'; +export declare type WithFaceExpressions = TSource & { + expressions: FaceExpressions; +}; +export declare function isWithFaceExpressions(obj: any): obj is WithFaceExpressions<{}>; +export declare function extendWithFaceExpressions(sourceObj: TSource, expressions: FaceExpressions): WithFaceExpressions; diff --git a/build/factories/WithFaceExpressions.js b/build/factories/WithFaceExpressions.js new file mode 100644 index 0000000..933e101 --- /dev/null +++ b/build/factories/WithFaceExpressions.js @@ -0,0 +1,9 @@ +import { FaceExpressions } from '../faceExpressionNet/FaceExpressions'; +export function isWithFaceExpressions(obj) { + return obj['expressions'] instanceof FaceExpressions; +} +export function extendWithFaceExpressions(sourceObj, expressions) { + const extension = { expressions }; + return Object.assign({}, sourceObj, extension); +} +//# sourceMappingURL=WithFaceExpressions.js.map \ No newline at end of file diff --git a/build/factories/WithFaceExpressions.js.map b/build/factories/WithFaceExpressions.js.map new file mode 100644 index 0000000..9373182 --- /dev/null +++ b/build/factories/WithFaceExpressions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WithFaceExpressions.js","sourceRoot":"","sources":["../../src/factories/WithFaceExpressions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAMvE,MAAM,UAAU,qBAAqB,CAAC,GAAQ;IAC5C,OAAO,GAAG,CAAC,aAAa,CAAC,YAAY,eAAe,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,yBAAyB,CAGvC,SAAkB,EAClB,WAA4B;IAG5B,MAAM,SAAS,GAAG,EAAE,WAAW,EAAE,CAAA;IACjC,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;AAChD,CAAC"} \ No newline at end of file diff --git a/build/factories/WithFaceLandmarks.d.ts b/build/factories/WithFaceLandmarks.d.ts new file mode 100644 index 0000000..99b9315 --- /dev/null +++ b/build/factories/WithFaceLandmarks.d.ts @@ -0,0 +1,11 @@ +import { FaceDetection } from '../classes/FaceDetection'; +import { FaceLandmarks } from '../classes/FaceLandmarks'; +import { FaceLandmarks68 } from '../classes/FaceLandmarks68'; +import { WithFaceDetection } from './WithFaceDetection'; +export declare type WithFaceLandmarks, TFaceLandmarks extends FaceLandmarks = FaceLandmarks68> = TSource & { + landmarks: TFaceLandmarks; + unshiftedLandmarks: TFaceLandmarks; + alignedRect: FaceDetection; +}; +export declare function isWithFaceLandmarks(obj: any): obj is WithFaceLandmarks, FaceLandmarks>; +export declare function extendWithFaceLandmarks, TFaceLandmarks extends FaceLandmarks = FaceLandmarks68>(sourceObj: TSource, unshiftedLandmarks: TFaceLandmarks): WithFaceLandmarks; diff --git a/build/factories/WithFaceLandmarks.js b/build/factories/WithFaceLandmarks.js new file mode 100644 index 0000000..2df14d1 --- /dev/null +++ b/build/factories/WithFaceLandmarks.js @@ -0,0 +1,23 @@ +import { FaceDetection } from '../classes/FaceDetection'; +import { FaceLandmarks } from '../classes/FaceLandmarks'; +import { isWithFaceDetection } from './WithFaceDetection'; +export function isWithFaceLandmarks(obj) { + return isWithFaceDetection(obj) + && obj['landmarks'] instanceof FaceLandmarks + && obj['unshiftedLandmarks'] instanceof FaceLandmarks + && obj['alignedRect'] instanceof FaceDetection; +} +export function extendWithFaceLandmarks(sourceObj, unshiftedLandmarks) { + const { box: shift } = sourceObj.detection; + const landmarks = unshiftedLandmarks.shiftBy(shift.x, shift.y); + const rect = landmarks.align(); + const { imageDims } = sourceObj.detection; + const alignedRect = new FaceDetection(sourceObj.detection.score, rect.rescale(imageDims.reverse()), imageDims); + const extension = { + landmarks, + unshiftedLandmarks, + alignedRect + }; + return Object.assign({}, sourceObj, extension); +} +//# sourceMappingURL=WithFaceLandmarks.js.map \ No newline at end of file diff --git a/build/factories/WithFaceLandmarks.js.map b/build/factories/WithFaceLandmarks.js.map new file mode 100644 index 0000000..8998504 --- /dev/null +++ b/build/factories/WithFaceLandmarks.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WithFaceLandmarks.js","sourceRoot":"","sources":["../../src/factories/WithFaceLandmarks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EAAE,mBAAmB,EAAqB,MAAM,qBAAqB,CAAC;AAW7E,MAAM,UAAU,mBAAmB,CAAC,GAAQ;IAC1C,OAAO,mBAAmB,CAAC,GAAG,CAAC;WAC1B,GAAG,CAAC,WAAW,CAAC,YAAY,aAAa;WACzC,GAAG,CAAC,oBAAoB,CAAC,YAAY,aAAa;WAClD,GAAG,CAAC,aAAa,CAAC,YAAY,aAAa,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,uBAAuB,CAIrC,SAAkB,EAClB,kBAAkC;IAGlC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,SAAS,CAAA;IAC1C,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAiB,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;IAE9E,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,CAAA;IAC9B,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC,SAAS,CAAA;IACzC,MAAM,WAAW,GAAG,IAAI,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,EAAE,SAAS,CAAC,CAAA;IAE9G,MAAM,SAAS,GAAG;QAChB,SAAS;QACT,kBAAkB;QAClB,WAAW;KACZ,CAAA;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;AAChD,CAAC"} \ No newline at end of file diff --git a/build/factories/WithGender.d.ts b/build/factories/WithGender.d.ts new file mode 100644 index 0000000..6f26c11 --- /dev/null +++ b/build/factories/WithGender.d.ts @@ -0,0 +1,7 @@ +import { Gender } from '../ageGenderNet/types'; +export declare type WithGender = TSource & { + gender: Gender; + genderProbability: number; +}; +export declare function isWithGender(obj: any): obj is WithGender<{}>; +export declare function extendWithGender(sourceObj: TSource, gender: Gender, genderProbability: number): WithGender; diff --git a/build/factories/WithGender.js b/build/factories/WithGender.js new file mode 100644 index 0000000..d6535be --- /dev/null +++ b/build/factories/WithGender.js @@ -0,0 +1,11 @@ +import { Gender } from '../ageGenderNet/types'; +import { isValidProbablitiy } from '../utils'; +export function isWithGender(obj) { + return (obj['gender'] === Gender.MALE || obj['gender'] === Gender.FEMALE) + && isValidProbablitiy(obj['genderProbability']); +} +export function extendWithGender(sourceObj, gender, genderProbability) { + const extension = { gender, genderProbability }; + return Object.assign({}, sourceObj, extension); +} +//# sourceMappingURL=WithGender.js.map \ No newline at end of file diff --git a/build/factories/WithGender.js.map b/build/factories/WithGender.js.map new file mode 100644 index 0000000..17fbf68 --- /dev/null +++ b/build/factories/WithGender.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WithGender.js","sourceRoot":"","sources":["../../src/factories/WithGender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAO9C,MAAM,UAAU,YAAY,CAAC,GAAQ;IACnC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC;WACpE,kBAAkB,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAA;AACnD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAG9B,SAAkB,EAClB,MAAc,EACd,iBAAyB;IAGzB,MAAM,SAAS,GAAG,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC/C,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;AAChD,CAAC"} \ No newline at end of file diff --git a/build/factories/index.d.ts b/build/factories/index.d.ts new file mode 100644 index 0000000..c5094ab --- /dev/null +++ b/build/factories/index.d.ts @@ -0,0 +1,6 @@ +export * from './WithFaceDescriptor'; +export * from './WithFaceDetection'; +export * from './WithFaceExpressions'; +export * from './WithFaceLandmarks'; +export * from './WithAge'; +export * from './WithGender'; diff --git a/build/factories/index.js b/build/factories/index.js new file mode 100644 index 0000000..0143670 --- /dev/null +++ b/build/factories/index.js @@ -0,0 +1,7 @@ +export * from './WithFaceDescriptor'; +export * from './WithFaceDetection'; +export * from './WithFaceExpressions'; +export * from './WithFaceLandmarks'; +export * from './WithAge'; +export * from './WithGender'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/factories/index.js.map b/build/factories/index.js.map new file mode 100644 index 0000000..6e643a8 --- /dev/null +++ b/build/factories/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/factories/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA"} \ No newline at end of file diff --git a/build/globalApi/ComposableTask.d.ts b/build/globalApi/ComposableTask.d.ts new file mode 100644 index 0000000..b7203e3 --- /dev/null +++ b/build/globalApi/ComposableTask.d.ts @@ -0,0 +1,4 @@ +export declare class ComposableTask { + then(onfulfilled: (value: T) => T | PromiseLike): Promise; + run(): Promise; +} diff --git a/build/globalApi/ComposableTask.js b/build/globalApi/ComposableTask.js new file mode 100644 index 0000000..7dde649 --- /dev/null +++ b/build/globalApi/ComposableTask.js @@ -0,0 +1,9 @@ +export class ComposableTask { + async then(onfulfilled) { + return onfulfilled(await this.run()); + } + async run() { + throw new Error('ComposableTask - run is not implemented'); + } +} +//# sourceMappingURL=ComposableTask.js.map \ No newline at end of file diff --git a/build/globalApi/ComposableTask.js.map b/build/globalApi/ComposableTask.js.map new file mode 100644 index 0000000..7190c1a --- /dev/null +++ b/build/globalApi/ComposableTask.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ComposableTask.js","sourceRoot":"","sources":["../../src/globalApi/ComposableTask.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,cAAc;IAElB,KAAK,CAAC,IAAI,CACf,WAA6C;QAE7C,OAAO,WAAW,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;IACtC,CAAC;IAEM,KAAK,CAAC,GAAG;QACd,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;IAC5D,CAAC;CACF"} \ No newline at end of file diff --git a/build/globalApi/ComputeFaceDescriptorsTasks.d.ts b/build/globalApi/ComputeFaceDescriptorsTasks.d.ts new file mode 100644 index 0000000..a17900b --- /dev/null +++ b/build/globalApi/ComputeFaceDescriptorsTasks.d.ts @@ -0,0 +1,22 @@ +import { TNetInput } from '../dom'; +import { WithFaceDescriptor } from '../factories/WithFaceDescriptor'; +import { WithFaceDetection } from '../factories/WithFaceDetection'; +import { WithFaceLandmarks } from '../factories/WithFaceLandmarks'; +import { ComposableTask } from './ComposableTask'; +import { PredictAllAgeAndGenderWithFaceAlignmentTask, PredictSingleAgeAndGenderWithFaceAlignmentTask } from './PredictAgeAndGenderTask'; +import { PredictAllFaceExpressionsWithFaceAlignmentTask, PredictSingleFaceExpressionsWithFaceAlignmentTask } from './PredictFaceExpressionsTask'; +export declare class ComputeFaceDescriptorsTaskBase extends ComposableTask { + protected parentTask: ComposableTask | Promise; + protected input: TNetInput; + constructor(parentTask: ComposableTask | Promise, input: TNetInput); +} +export declare class ComputeAllFaceDescriptorsTask>> extends ComputeFaceDescriptorsTaskBase[], TSource[]> { + run(): Promise[]>; + withFaceExpressions(): PredictAllFaceExpressionsWithFaceAlignmentTask>; + withAgeAndGender(): PredictAllAgeAndGenderWithFaceAlignmentTask>; +} +export declare class ComputeSingleFaceDescriptorTask>> extends ComputeFaceDescriptorsTaskBase | undefined, TSource | undefined> { + run(): Promise | undefined>; + withFaceExpressions(): PredictSingleFaceExpressionsWithFaceAlignmentTask>; + withAgeAndGender(): PredictSingleAgeAndGenderWithFaceAlignmentTask>; +} diff --git a/build/globalApi/ComputeFaceDescriptorsTasks.js b/build/globalApi/ComputeFaceDescriptorsTasks.js new file mode 100644 index 0000000..45b9e48 --- /dev/null +++ b/build/globalApi/ComputeFaceDescriptorsTasks.js @@ -0,0 +1,43 @@ +import { extendWithFaceDescriptor } from '../factories/WithFaceDescriptor'; +import { ComposableTask } from './ComposableTask'; +import { extractAllFacesAndComputeResults, extractSingleFaceAndComputeResult } from './extractFacesAndComputeResults'; +import { nets } from './nets'; +import { PredictAllAgeAndGenderWithFaceAlignmentTask, PredictSingleAgeAndGenderWithFaceAlignmentTask, } from './PredictAgeAndGenderTask'; +import { PredictAllFaceExpressionsWithFaceAlignmentTask, PredictSingleFaceExpressionsWithFaceAlignmentTask, } from './PredictFaceExpressionsTask'; +export class ComputeFaceDescriptorsTaskBase extends ComposableTask { + constructor(parentTask, input) { + super(); + this.parentTask = parentTask; + this.input = input; + } +} +export class ComputeAllFaceDescriptorsTask extends ComputeFaceDescriptorsTaskBase { + async run() { + const parentResults = await this.parentTask; + const descriptors = await extractAllFacesAndComputeResults(parentResults, this.input, faces => Promise.all(faces.map(face => nets.faceRecognitionNet.computeFaceDescriptor(face))), null, parentResult => parentResult.landmarks.align(null, { useDlibAlignment: true })); + return descriptors.map((descriptor, i) => extendWithFaceDescriptor(parentResults[i], descriptor)); + } + withFaceExpressions() { + return new PredictAllFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withAgeAndGender() { + return new PredictAllAgeAndGenderWithFaceAlignmentTask(this, this.input); + } +} +export class ComputeSingleFaceDescriptorTask extends ComputeFaceDescriptorsTaskBase { + async run() { + const parentResult = await this.parentTask; + if (!parentResult) { + return; + } + const descriptor = await extractSingleFaceAndComputeResult(parentResult, this.input, face => nets.faceRecognitionNet.computeFaceDescriptor(face), null, parentResult => parentResult.landmarks.align(null, { useDlibAlignment: true })); + return extendWithFaceDescriptor(parentResult, descriptor); + } + withFaceExpressions() { + return new PredictSingleFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withAgeAndGender() { + return new PredictSingleAgeAndGenderWithFaceAlignmentTask(this, this.input); + } +} +//# sourceMappingURL=ComputeFaceDescriptorsTasks.js.map \ No newline at end of file diff --git a/build/globalApi/ComputeFaceDescriptorsTasks.js.map b/build/globalApi/ComputeFaceDescriptorsTasks.js.map new file mode 100644 index 0000000..90b25c5 --- /dev/null +++ b/build/globalApi/ComputeFaceDescriptorsTasks.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ComputeFaceDescriptorsTasks.js","sourceRoot":"","sources":["../../src/globalApi/ComputeFaceDescriptorsTasks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAsB,MAAM,iCAAiC,CAAC;AAG/F,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,gCAAgC,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AACtH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EACL,2CAA2C,EAC3C,8CAA8C,GAC/C,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,8CAA8C,EAC9C,iDAAiD,GAClD,MAAM,8BAA8B,CAAC;AAEtC,MAAM,OAAO,8BAAuD,SAAQ,cAAuB;IACjG,YACY,UAAkE,EAClE,KAAgB;QAE1B,KAAK,EAAE,CAAA;QAHG,eAAU,GAAV,UAAU,CAAwD;QAClE,UAAK,GAAL,KAAK,CAAW;IAG5B,CAAC;CACF;AAED,MAAM,OAAO,6BAEX,SAAQ,8BAAwE;IAEzE,KAAK,CAAC,GAAG;QAEd,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,UAAU,CAAA;QAE3C,MAAM,WAAW,GAAG,MAAM,gCAAgC,CACxD,aAAa,EACb,IAAI,CAAC,KAAK,EACV,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CACpC,IAAI,CAAC,kBAAkB,CAAC,qBAAqB,CAAC,IAAI,CAA0B,CAC7E,CAAC,EACF,IAAI,EACJ,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAC/E,CAAA;QAED,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,wBAAwB,CAAU,aAAa,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAA;IAC5G,CAAC;IAED,mBAAmB;QACjB,OAAO,IAAI,8CAA8C,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAC7E,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,2CAA2C,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1E,CAAC;CACF;AAED,MAAM,OAAO,+BAEX,SAAQ,8BAA4F;IAE7F,KAAK,CAAC,GAAG;QAEd,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,UAAU,CAAA;QAC1C,IAAI,CAAC,YAAY,EAAE;YACjB,OAAM;SACP;QACD,MAAM,UAAU,GAAG,MAAM,iCAAiC,CACxD,YAAY,EACZ,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,qBAAqB,CAAC,IAAI,CAA0B,EACpF,IAAI,EACJ,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAC/E,CAAA;QAED,OAAO,wBAAwB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IAC3D,CAAC;IAED,mBAAmB;QACjB,OAAO,IAAI,iDAAiD,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAChF,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,8CAA8C,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAC7E,CAAC;CACF"} \ No newline at end of file diff --git a/build/globalApi/DetectFaceLandmarksTasks.d.ts b/build/globalApi/DetectFaceLandmarksTasks.d.ts new file mode 100644 index 0000000..53b6fd8 --- /dev/null +++ b/build/globalApi/DetectFaceLandmarksTasks.d.ts @@ -0,0 +1,29 @@ +import { FaceLandmarks68 } from '../classes/FaceLandmarks68'; +import { TNetInput } from '../dom'; +import { FaceLandmark68Net } from '../faceLandmarkNet/FaceLandmark68Net'; +import { FaceLandmark68TinyNet } from '../faceLandmarkNet/FaceLandmark68TinyNet'; +import { WithFaceDetection } from '../factories/WithFaceDetection'; +import { WithFaceLandmarks } from '../factories/WithFaceLandmarks'; +import { ComposableTask } from './ComposableTask'; +import { ComputeAllFaceDescriptorsTask, ComputeSingleFaceDescriptorTask } from './ComputeFaceDescriptorsTasks'; +import { PredictAllAgeAndGenderWithFaceAlignmentTask, PredictSingleAgeAndGenderWithFaceAlignmentTask } from './PredictAgeAndGenderTask'; +import { PredictAllFaceExpressionsWithFaceAlignmentTask, PredictSingleFaceExpressionsWithFaceAlignmentTask } from './PredictFaceExpressionsTask'; +export declare class DetectFaceLandmarksTaskBase extends ComposableTask { + protected parentTask: ComposableTask | Promise; + protected input: TNetInput; + protected useTinyLandmarkNet: boolean; + constructor(parentTask: ComposableTask | Promise, input: TNetInput, useTinyLandmarkNet: boolean); + protected get landmarkNet(): FaceLandmark68Net | FaceLandmark68TinyNet; +} +export declare class DetectAllFaceLandmarksTask> extends DetectFaceLandmarksTaskBase[], TSource[]> { + run(): Promise[]>; + withFaceExpressions(): PredictAllFaceExpressionsWithFaceAlignmentTask>; + withAgeAndGender(): PredictAllAgeAndGenderWithFaceAlignmentTask>; + withFaceDescriptors(): ComputeAllFaceDescriptorsTask>; +} +export declare class DetectSingleFaceLandmarksTask> extends DetectFaceLandmarksTaskBase | undefined, TSource | undefined> { + run(): Promise | undefined>; + withFaceExpressions(): PredictSingleFaceExpressionsWithFaceAlignmentTask>; + withAgeAndGender(): PredictSingleAgeAndGenderWithFaceAlignmentTask>; + withFaceDescriptor(): ComputeSingleFaceDescriptorTask>; +} diff --git a/build/globalApi/DetectFaceLandmarksTasks.js b/build/globalApi/DetectFaceLandmarksTasks.js new file mode 100644 index 0000000..96c7a6f --- /dev/null +++ b/build/globalApi/DetectFaceLandmarksTasks.js @@ -0,0 +1,67 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { extractFaces, extractFaceTensors } from '../dom'; +import { extendWithFaceLandmarks } from '../factories/WithFaceLandmarks'; +import { ComposableTask } from './ComposableTask'; +import { ComputeAllFaceDescriptorsTask, ComputeSingleFaceDescriptorTask } from './ComputeFaceDescriptorsTasks'; +import { nets } from './nets'; +import { PredictAllAgeAndGenderWithFaceAlignmentTask, PredictSingleAgeAndGenderWithFaceAlignmentTask, } from './PredictAgeAndGenderTask'; +import { PredictAllFaceExpressionsWithFaceAlignmentTask, PredictSingleFaceExpressionsWithFaceAlignmentTask, } from './PredictFaceExpressionsTask'; +export class DetectFaceLandmarksTaskBase extends ComposableTask { + constructor(parentTask, input, useTinyLandmarkNet) { + super(); + this.parentTask = parentTask; + this.input = input; + this.useTinyLandmarkNet = useTinyLandmarkNet; + } + get landmarkNet() { + return this.useTinyLandmarkNet + ? nets.faceLandmark68TinyNet + : nets.faceLandmark68Net; + } +} +export class DetectAllFaceLandmarksTask extends DetectFaceLandmarksTaskBase { + async run() { + const parentResults = await this.parentTask; + const detections = parentResults.map(res => res.detection); + const faces = this.input instanceof tf.Tensor + ? await extractFaceTensors(this.input, detections) + : await extractFaces(this.input, detections); + const faceLandmarksByFace = await Promise.all(faces.map(face => this.landmarkNet.detectLandmarks(face))); + faces.forEach(f => f instanceof tf.Tensor && f.dispose()); + return parentResults.map((parentResult, i) => extendWithFaceLandmarks(parentResult, faceLandmarksByFace[i])); + } + withFaceExpressions() { + return new PredictAllFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withAgeAndGender() { + return new PredictAllAgeAndGenderWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptors() { + return new ComputeAllFaceDescriptorsTask(this, this.input); + } +} +export class DetectSingleFaceLandmarksTask extends DetectFaceLandmarksTaskBase { + async run() { + const parentResult = await this.parentTask; + if (!parentResult) { + return; + } + const { detection } = parentResult; + const faces = this.input instanceof tf.Tensor + ? await extractFaceTensors(this.input, [detection]) + : await extractFaces(this.input, [detection]); + const landmarks = await this.landmarkNet.detectLandmarks(faces[0]); + faces.forEach(f => f instanceof tf.Tensor && f.dispose()); + return extendWithFaceLandmarks(parentResult, landmarks); + } + withFaceExpressions() { + return new PredictSingleFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withAgeAndGender() { + return new PredictSingleAgeAndGenderWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptor() { + return new ComputeSingleFaceDescriptorTask(this, this.input); + } +} +//# sourceMappingURL=DetectFaceLandmarksTasks.js.map \ No newline at end of file diff --git a/build/globalApi/DetectFaceLandmarksTasks.js.map b/build/globalApi/DetectFaceLandmarksTasks.js.map new file mode 100644 index 0000000..a749f82 --- /dev/null +++ b/build/globalApi/DetectFaceLandmarksTasks.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DetectFaceLandmarksTasks.js","sourceRoot":"","sources":["../../src/globalApi/DetectFaceLandmarksTasks.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/globalApi/DetectFacesTasks.d.ts b/build/globalApi/DetectFacesTasks.d.ts new file mode 100644 index 0000000..1da11c5 --- /dev/null +++ b/build/globalApi/DetectFacesTasks.d.ts @@ -0,0 +1,38 @@ +import { FaceDetection } from '../classes/FaceDetection'; +import { TNetInput } from '../dom'; +import { ComposableTask } from './ComposableTask'; +import { DetectAllFaceLandmarksTask, DetectSingleFaceLandmarksTask } from './DetectFaceLandmarksTasks'; +import { PredictAllAgeAndGenderTask, PredictSingleAgeAndGenderTask } from './PredictAgeAndGenderTask'; +import { PredictAllFaceExpressionsTask, PredictSingleFaceExpressionsTask } from './PredictFaceExpressionsTask'; +import { FaceDetectionOptions } from './types'; +export declare class DetectFacesTaskBase extends ComposableTask { + protected input: TNetInput; + protected options: FaceDetectionOptions; + constructor(input: TNetInput, options?: FaceDetectionOptions); +} +export declare class DetectAllFacesTask extends DetectFacesTaskBase { + run(): Promise; + private runAndExtendWithFaceDetections; + withFaceLandmarks(useTinyLandmarkNet?: boolean): DetectAllFaceLandmarksTask<{ + detection: FaceDetection; + }>; + withFaceExpressions(): PredictAllFaceExpressionsTask<{ + detection: FaceDetection; + }>; + withAgeAndGender(): PredictAllAgeAndGenderTask<{ + detection: FaceDetection; + }>; +} +export declare class DetectSingleFaceTask extends DetectFacesTaskBase { + run(): Promise; + private runAndExtendWithFaceDetection; + withFaceLandmarks(useTinyLandmarkNet?: boolean): DetectSingleFaceLandmarksTask<{ + detection: FaceDetection; + }>; + withFaceExpressions(): PredictSingleFaceExpressionsTask<{ + detection: FaceDetection; + }>; + withAgeAndGender(): PredictSingleAgeAndGenderTask<{ + detection: FaceDetection; + }>; +} diff --git a/build/globalApi/DetectFacesTasks.js b/build/globalApi/DetectFacesTasks.js new file mode 100644 index 0000000..2aa9b62 --- /dev/null +++ b/build/globalApi/DetectFacesTasks.js @@ -0,0 +1,69 @@ +import { extendWithFaceDetection } from '../factories/WithFaceDetection'; +import { TinyFaceDetectorOptions } from '../tinyFaceDetector/TinyFaceDetectorOptions'; +import { ComposableTask } from './ComposableTask'; +import { DetectAllFaceLandmarksTask, DetectSingleFaceLandmarksTask } from './DetectFaceLandmarksTasks'; +import { nets } from './nets'; +import { PredictAllAgeAndGenderTask, PredictSingleAgeAndGenderTask } from './PredictAgeAndGenderTask'; +import { PredictAllFaceExpressionsTask, PredictSingleFaceExpressionsTask } from './PredictFaceExpressionsTask'; +export class DetectFacesTaskBase extends ComposableTask { + constructor(input, options = new TinyFaceDetectorOptions()) { + super(); + this.input = input; + this.options = options; + } +} +export class DetectAllFacesTask extends DetectFacesTaskBase { + async run() { + const { input, options } = this; + const faceDetectionFunction = options instanceof TinyFaceDetectorOptions + ? (input) => nets.tinyFaceDetector.locateFaces(input, options) + : null; + if (!faceDetectionFunction) { + throw new Error('detectFaces - expected options to be instance of TinyFaceDetectorOptions | SsdMobilenetv1Options | MtcnnOptions | TinyYolov2Options'); + } + return faceDetectionFunction(input); + } + runAndExtendWithFaceDetections() { + return new Promise(async (res) => { + const detections = await this.run(); + return res(detections.map(detection => extendWithFaceDetection({}, detection))); + }); + } + withFaceLandmarks(useTinyLandmarkNet = false) { + return new DetectAllFaceLandmarksTask(this.runAndExtendWithFaceDetections(), this.input, useTinyLandmarkNet); + } + withFaceExpressions() { + return new PredictAllFaceExpressionsTask(this.runAndExtendWithFaceDetections(), this.input); + } + withAgeAndGender() { + return new PredictAllAgeAndGenderTask(this.runAndExtendWithFaceDetections(), this.input); + } +} +export class DetectSingleFaceTask extends DetectFacesTaskBase { + async run() { + const faceDetections = await new DetectAllFacesTask(this.input, this.options); + let faceDetectionWithHighestScore = faceDetections[0]; + faceDetections.forEach(faceDetection => { + if (faceDetection.score > faceDetectionWithHighestScore.score) { + faceDetectionWithHighestScore = faceDetection; + } + }); + return faceDetectionWithHighestScore; + } + runAndExtendWithFaceDetection() { + return new Promise(async (res) => { + const detection = await this.run(); + return res(detection ? extendWithFaceDetection({}, detection) : undefined); + }); + } + withFaceLandmarks(useTinyLandmarkNet = false) { + return new DetectSingleFaceLandmarksTask(this.runAndExtendWithFaceDetection(), this.input, useTinyLandmarkNet); + } + withFaceExpressions() { + return new PredictSingleFaceExpressionsTask(this.runAndExtendWithFaceDetection(), this.input); + } + withAgeAndGender() { + return new PredictSingleAgeAndGenderTask(this.runAndExtendWithFaceDetection(), this.input); + } +} +//# sourceMappingURL=DetectFacesTasks.js.map \ No newline at end of file diff --git a/build/globalApi/DetectFacesTasks.js.map b/build/globalApi/DetectFacesTasks.js.map new file mode 100644 index 0000000..4abdb78 --- /dev/null +++ b/build/globalApi/DetectFacesTasks.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DetectFacesTasks.js","sourceRoot":"","sources":["../../src/globalApi/DetectFacesTasks.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/globalApi/FaceMatcher.d.ts b/build/globalApi/FaceMatcher.d.ts new file mode 100644 index 0000000..4479ca0 --- /dev/null +++ b/build/globalApi/FaceMatcher.d.ts @@ -0,0 +1,15 @@ +import { FaceMatch } from '../classes/FaceMatch'; +import { LabeledFaceDescriptors } from '../classes/LabeledFaceDescriptors'; +import { WithFaceDescriptor } from '../factories'; +export declare class FaceMatcher { + private _labeledDescriptors; + private _distanceThreshold; + constructor(inputs: LabeledFaceDescriptors | WithFaceDescriptor | Float32Array | Array | Float32Array>, distanceThreshold?: number); + get labeledDescriptors(): LabeledFaceDescriptors[]; + get distanceThreshold(): number; + computeMeanDistance(queryDescriptor: Float32Array, descriptors: Float32Array[]): number; + matchDescriptor(queryDescriptor: Float32Array): FaceMatch; + findBestMatch(queryDescriptor: Float32Array): FaceMatch; + toJSON(): any; + static fromJSON(json: any): FaceMatcher; +} diff --git a/build/globalApi/FaceMatcher.js b/build/globalApi/FaceMatcher.js new file mode 100644 index 0000000..b8e654b --- /dev/null +++ b/build/globalApi/FaceMatcher.js @@ -0,0 +1,57 @@ +import { FaceMatch } from '../classes/FaceMatch'; +import { LabeledFaceDescriptors } from '../classes/LabeledFaceDescriptors'; +import { euclideanDistance } from '../euclideanDistance'; +export class FaceMatcher { + constructor(inputs, distanceThreshold = 0.6) { + this._distanceThreshold = distanceThreshold; + const inputArray = Array.isArray(inputs) ? inputs : [inputs]; + if (!inputArray.length) { + throw new Error(`FaceRecognizer.constructor - expected atleast one input`); + } + let count = 1; + const createUniqueLabel = () => `person ${count++}`; + this._labeledDescriptors = inputArray.map((desc) => { + if (desc instanceof LabeledFaceDescriptors) { + return desc; + } + if (desc instanceof Float32Array) { + return new LabeledFaceDescriptors(createUniqueLabel(), [desc]); + } + if (desc.descriptor && desc.descriptor instanceof Float32Array) { + return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]); + } + throw new Error(`FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor | Float32Array | Array | Float32Array>`); + }); + } + get labeledDescriptors() { return this._labeledDescriptors; } + get distanceThreshold() { return this._distanceThreshold; } + computeMeanDistance(queryDescriptor, descriptors) { + return descriptors + .map(d => euclideanDistance(d, queryDescriptor)) + .reduce((d1, d2) => d1 + d2, 0) + / (descriptors.length || 1); + } + matchDescriptor(queryDescriptor) { + return this.labeledDescriptors + .map(({ descriptors, label }) => new FaceMatch(label, this.computeMeanDistance(queryDescriptor, descriptors))) + .reduce((best, curr) => best.distance < curr.distance ? best : curr); + } + findBestMatch(queryDescriptor) { + const bestMatch = this.matchDescriptor(queryDescriptor); + return bestMatch.distance < this.distanceThreshold + ? bestMatch + : new FaceMatch('unknown', bestMatch.distance); + } + toJSON() { + return { + distanceThreshold: this.distanceThreshold, + labeledDescriptors: this.labeledDescriptors.map((ld) => ld.toJSON()) + }; + } + static fromJSON(json) { + const labeledDescriptors = json.labeledDescriptors + .map((ld) => LabeledFaceDescriptors.fromJSON(ld)); + return new FaceMatcher(labeledDescriptors, json.distanceThreshold); + } +} +//# sourceMappingURL=FaceMatcher.js.map \ No newline at end of file diff --git a/build/globalApi/FaceMatcher.js.map b/build/globalApi/FaceMatcher.js.map new file mode 100644 index 0000000..867185e --- /dev/null +++ b/build/globalApi/FaceMatcher.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FaceMatcher.js","sourceRoot":"","sources":["../../src/globalApi/FaceMatcher.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/globalApi/PredictAgeAndGenderTask.d.ts b/build/globalApi/PredictAgeAndGenderTask.d.ts new file mode 100644 index 0000000..ec86a43 --- /dev/null +++ b/build/globalApi/PredictAgeAndGenderTask.d.ts @@ -0,0 +1,31 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { TNetInput } from '../dom'; +import { WithAge } from '../factories/WithAge'; +import { WithFaceDetection } from '../factories/WithFaceDetection'; +import { WithFaceLandmarks } from '../factories/WithFaceLandmarks'; +import { WithGender } from '../factories/WithGender'; +import { ComposableTask } from './ComposableTask'; +import { ComputeAllFaceDescriptorsTask, ComputeSingleFaceDescriptorTask } from './ComputeFaceDescriptorsTasks'; +import { PredictAllFaceExpressionsTask, PredictAllFaceExpressionsWithFaceAlignmentTask, PredictSingleFaceExpressionsTask, PredictSingleFaceExpressionsWithFaceAlignmentTask } from './PredictFaceExpressionsTask'; +export declare class PredictAgeAndGenderTaskBase extends ComposableTask { + protected parentTask: ComposableTask | Promise; + protected input: TNetInput; + protected extractedFaces?: (tf.Tensor3D | HTMLCanvasElement)[] | undefined; + constructor(parentTask: ComposableTask | Promise, input: TNetInput, extractedFaces?: (tf.Tensor3D | HTMLCanvasElement)[] | undefined); +} +export declare class PredictAllAgeAndGenderTask> extends PredictAgeAndGenderTaskBase>[], TSource[]> { + run(): Promise>[]>; + withFaceExpressions(): PredictAllFaceExpressionsTask>>; +} +export declare class PredictSingleAgeAndGenderTask> extends PredictAgeAndGenderTaskBase> | undefined, TSource | undefined> { + run(): Promise> | undefined>; + withFaceExpressions(): PredictSingleFaceExpressionsTask>>; +} +export declare class PredictAllAgeAndGenderWithFaceAlignmentTask>> extends PredictAllAgeAndGenderTask { + withFaceExpressions(): PredictAllFaceExpressionsWithFaceAlignmentTask>>; + withFaceDescriptors(): ComputeAllFaceDescriptorsTask>>; +} +export declare class PredictSingleAgeAndGenderWithFaceAlignmentTask>> extends PredictSingleAgeAndGenderTask { + withFaceExpressions(): PredictSingleFaceExpressionsWithFaceAlignmentTask>>; + withFaceDescriptor(): ComputeSingleFaceDescriptorTask>>; +} diff --git a/build/globalApi/PredictAgeAndGenderTask.js b/build/globalApi/PredictAgeAndGenderTask.js new file mode 100644 index 0000000..5a17aa8 --- /dev/null +++ b/build/globalApi/PredictAgeAndGenderTask.js @@ -0,0 +1,58 @@ +import { extendWithAge } from '../factories/WithAge'; +import { extendWithGender } from '../factories/WithGender'; +import { ComposableTask } from './ComposableTask'; +import { ComputeAllFaceDescriptorsTask, ComputeSingleFaceDescriptorTask } from './ComputeFaceDescriptorsTasks'; +import { extractAllFacesAndComputeResults, extractSingleFaceAndComputeResult } from './extractFacesAndComputeResults'; +import { nets } from './nets'; +import { PredictAllFaceExpressionsTask, PredictAllFaceExpressionsWithFaceAlignmentTask, PredictSingleFaceExpressionsTask, PredictSingleFaceExpressionsWithFaceAlignmentTask, } from './PredictFaceExpressionsTask'; +export class PredictAgeAndGenderTaskBase extends ComposableTask { + constructor(parentTask, input, extractedFaces) { + super(); + this.parentTask = parentTask; + this.input = input; + this.extractedFaces = extractedFaces; + } +} +export class PredictAllAgeAndGenderTask extends PredictAgeAndGenderTaskBase { + async run() { + const parentResults = await this.parentTask; + const ageAndGenderByFace = await extractAllFacesAndComputeResults(parentResults, this.input, async (faces) => await Promise.all(faces.map(face => nets.ageGenderNet.predictAgeAndGender(face))), this.extractedFaces); + return parentResults.map((parentResult, i) => { + const { age, gender, genderProbability } = ageAndGenderByFace[i]; + return extendWithAge(extendWithGender(parentResult, gender, genderProbability), age); + }); + } + withFaceExpressions() { + return new PredictAllFaceExpressionsTask(this, this.input); + } +} +export class PredictSingleAgeAndGenderTask extends PredictAgeAndGenderTaskBase { + async run() { + const parentResult = await this.parentTask; + if (!parentResult) { + return; + } + const { age, gender, genderProbability } = await extractSingleFaceAndComputeResult(parentResult, this.input, face => nets.ageGenderNet.predictAgeAndGender(face), this.extractedFaces); + return extendWithAge(extendWithGender(parentResult, gender, genderProbability), age); + } + withFaceExpressions() { + return new PredictSingleFaceExpressionsTask(this, this.input); + } +} +export class PredictAllAgeAndGenderWithFaceAlignmentTask extends PredictAllAgeAndGenderTask { + withFaceExpressions() { + return new PredictAllFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptors() { + return new ComputeAllFaceDescriptorsTask(this, this.input); + } +} +export class PredictSingleAgeAndGenderWithFaceAlignmentTask extends PredictSingleAgeAndGenderTask { + withFaceExpressions() { + return new PredictSingleFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptor() { + return new ComputeSingleFaceDescriptorTask(this, this.input); + } +} +//# sourceMappingURL=PredictAgeAndGenderTask.js.map \ No newline at end of file diff --git a/build/globalApi/PredictAgeAndGenderTask.js.map b/build/globalApi/PredictAgeAndGenderTask.js.map new file mode 100644 index 0000000..e18d85f --- /dev/null +++ b/build/globalApi/PredictAgeAndGenderTask.js.map @@ -0,0 +1 @@ +{"version":3,"file":"PredictAgeAndGenderTask.js","sourceRoot":"","sources":["../../src/globalApi/PredictAgeAndGenderTask.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/globalApi/PredictFaceExpressionsTask.d.ts b/build/globalApi/PredictFaceExpressionsTask.d.ts new file mode 100644 index 0000000..5e9961c --- /dev/null +++ b/build/globalApi/PredictFaceExpressionsTask.d.ts @@ -0,0 +1,30 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { TNetInput } from '../dom'; +import { WithFaceDetection } from '../factories/WithFaceDetection'; +import { WithFaceExpressions } from '../factories/WithFaceExpressions'; +import { WithFaceLandmarks } from '../factories/WithFaceLandmarks'; +import { ComposableTask } from './ComposableTask'; +import { ComputeAllFaceDescriptorsTask, ComputeSingleFaceDescriptorTask } from './ComputeFaceDescriptorsTasks'; +import { PredictAllAgeAndGenderTask, PredictAllAgeAndGenderWithFaceAlignmentTask, PredictSingleAgeAndGenderTask, PredictSingleAgeAndGenderWithFaceAlignmentTask } from './PredictAgeAndGenderTask'; +export declare class PredictFaceExpressionsTaskBase extends ComposableTask { + protected parentTask: ComposableTask | Promise; + protected input: TNetInput; + protected extractedFaces?: (tf.Tensor3D | HTMLCanvasElement)[] | undefined; + constructor(parentTask: ComposableTask | Promise, input: TNetInput, extractedFaces?: (tf.Tensor3D | HTMLCanvasElement)[] | undefined); +} +export declare class PredictAllFaceExpressionsTask> extends PredictFaceExpressionsTaskBase[], TSource[]> { + run(): Promise[]>; + withAgeAndGender(): PredictAllAgeAndGenderTask>; +} +export declare class PredictSingleFaceExpressionsTask> extends PredictFaceExpressionsTaskBase | undefined, TSource | undefined> { + run(): Promise | undefined>; + withAgeAndGender(): PredictSingleAgeAndGenderTask>; +} +export declare class PredictAllFaceExpressionsWithFaceAlignmentTask>> extends PredictAllFaceExpressionsTask { + withAgeAndGender(): PredictAllAgeAndGenderWithFaceAlignmentTask>; + withFaceDescriptors(): ComputeAllFaceDescriptorsTask>; +} +export declare class PredictSingleFaceExpressionsWithFaceAlignmentTask>> extends PredictSingleFaceExpressionsTask { + withAgeAndGender(): PredictSingleAgeAndGenderWithFaceAlignmentTask>; + withFaceDescriptor(): ComputeSingleFaceDescriptorTask>; +} diff --git a/build/globalApi/PredictFaceExpressionsTask.js b/build/globalApi/PredictFaceExpressionsTask.js new file mode 100644 index 0000000..7c528af --- /dev/null +++ b/build/globalApi/PredictFaceExpressionsTask.js @@ -0,0 +1,54 @@ +import { extendWithFaceExpressions } from '../factories/WithFaceExpressions'; +import { ComposableTask } from './ComposableTask'; +import { ComputeAllFaceDescriptorsTask, ComputeSingleFaceDescriptorTask } from './ComputeFaceDescriptorsTasks'; +import { extractAllFacesAndComputeResults, extractSingleFaceAndComputeResult } from './extractFacesAndComputeResults'; +import { nets } from './nets'; +import { PredictAllAgeAndGenderTask, PredictAllAgeAndGenderWithFaceAlignmentTask, PredictSingleAgeAndGenderTask, PredictSingleAgeAndGenderWithFaceAlignmentTask, } from './PredictAgeAndGenderTask'; +export class PredictFaceExpressionsTaskBase extends ComposableTask { + constructor(parentTask, input, extractedFaces) { + super(); + this.parentTask = parentTask; + this.input = input; + this.extractedFaces = extractedFaces; + } +} +export class PredictAllFaceExpressionsTask extends PredictFaceExpressionsTaskBase { + async run() { + const parentResults = await this.parentTask; + const faceExpressionsByFace = await extractAllFacesAndComputeResults(parentResults, this.input, async (faces) => await Promise.all(faces.map(face => nets.faceExpressionNet.predictExpressions(face))), this.extractedFaces); + return parentResults.map((parentResult, i) => extendWithFaceExpressions(parentResult, faceExpressionsByFace[i])); + } + withAgeAndGender() { + return new PredictAllAgeAndGenderTask(this, this.input); + } +} +export class PredictSingleFaceExpressionsTask extends PredictFaceExpressionsTaskBase { + async run() { + const parentResult = await this.parentTask; + if (!parentResult) { + return; + } + const faceExpressions = await extractSingleFaceAndComputeResult(parentResult, this.input, face => nets.faceExpressionNet.predictExpressions(face), this.extractedFaces); + return extendWithFaceExpressions(parentResult, faceExpressions); + } + withAgeAndGender() { + return new PredictSingleAgeAndGenderTask(this, this.input); + } +} +export class PredictAllFaceExpressionsWithFaceAlignmentTask extends PredictAllFaceExpressionsTask { + withAgeAndGender() { + return new PredictAllAgeAndGenderWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptors() { + return new ComputeAllFaceDescriptorsTask(this, this.input); + } +} +export class PredictSingleFaceExpressionsWithFaceAlignmentTask extends PredictSingleFaceExpressionsTask { + withAgeAndGender() { + return new PredictSingleAgeAndGenderWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptor() { + return new ComputeSingleFaceDescriptorTask(this, this.input); + } +} +//# sourceMappingURL=PredictFaceExpressionsTask.js.map \ No newline at end of file diff --git a/build/globalApi/PredictFaceExpressionsTask.js.map b/build/globalApi/PredictFaceExpressionsTask.js.map new file mode 100644 index 0000000..eb91708 --- /dev/null +++ b/build/globalApi/PredictFaceExpressionsTask.js.map @@ -0,0 +1 @@ +{"version":3,"file":"PredictFaceExpressionsTask.js","sourceRoot":"","sources":["../../src/globalApi/PredictFaceExpressionsTask.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,yBAAyB,EAAuB,MAAM,kCAAkC,CAAC;AAElG,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,6BAA6B,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAC/G,OAAO,EAAE,gCAAgC,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AACtH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EACL,0BAA0B,EAC1B,2CAA2C,EAC3C,6BAA6B,EAC7B,8CAA8C,GAC/C,MAAM,2BAA2B,CAAC;AAEnC,MAAM,OAAO,8BAAuD,SAAQ,cAAuB;IACjG,YACY,UAAkE,EAClE,KAAgB,EAChB,cAAuD;QAEjE,KAAK,EAAE,CAAA;QAJG,eAAU,GAAV,UAAU,CAAwD;QAClE,UAAK,GAAL,KAAK,CAAW;QAChB,mBAAc,GAAd,cAAc,CAAyC;IAGnE,CAAC;CACF;AAED,MAAM,OAAO,6BAEX,SAAQ,8BAAyE;IAE1E,KAAK,CAAC,GAAG;QAEd,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,UAAU,CAAA;QAE3C,MAAM,qBAAqB,GAAG,MAAM,gCAAgC,CAClE,aAAa,EACb,IAAI,CAAC,KAAK,EACV,KAAK,EAAC,KAAK,EAAC,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CACxC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,IAAI,CAA6B,CACpF,CAAC,EACF,IAAI,CAAC,cAAc,CACpB,CAAA;QAED,OAAO,aAAa,CAAC,GAAG,CACtB,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC,yBAAyB,CAAU,YAAY,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAChG,CAAA;IACH,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,0BAA0B,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IACzD,CAAC;CACF;AAED,MAAM,OAAO,gCAEV,SAAQ,8BAA6F;IAE/F,KAAK,CAAC,GAAG;QAEd,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,UAAU,CAAA;QAC1C,IAAI,CAAC,YAAY,EAAE;YACjB,OAAM;SACP;QAED,MAAM,eAAe,GAAG,MAAM,iCAAiC,CAC7D,YAAY,EACZ,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,IAAI,CAA6B,EACnF,IAAI,CAAC,cAAc,CACpB,CAAA;QAED,OAAO,yBAAyB,CAAC,YAAY,EAAE,eAAe,CAAC,CAAA;IACjE,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,6BAA6B,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5D,CAAC;CACF;AAED,MAAM,OAAO,8CAEX,SAAQ,6BAAsC;IAE9C,gBAAgB;QACd,OAAO,IAAI,2CAA2C,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1E,CAAC;IAED,mBAAmB;QACjB,OAAO,IAAI,6BAA6B,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5D,CAAC;CACF;AAED,MAAM,OAAO,iDAEX,SAAQ,gCAAyC;IAEjD,gBAAgB;QACd,OAAO,IAAI,8CAA8C,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAC7E,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,+BAA+B,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAC9D,CAAC;CACF"} \ No newline at end of file diff --git a/build/globalApi/allFaces.d.ts b/build/globalApi/allFaces.d.ts new file mode 100644 index 0000000..8bf0ad2 --- /dev/null +++ b/build/globalApi/allFaces.d.ts @@ -0,0 +1,5 @@ +import { TNetInput } from '../dom'; +import { WithFaceDescriptor, WithFaceDetection, WithFaceLandmarks } from '../factories'; +import { ITinyYolov2Options } from '../tinyYolov2'; +export declare function allFacesTinyYolov2(input: TNetInput, forwardParams?: ITinyYolov2Options): Promise>>[]>; +export declare const allFaces: typeof allFacesTinyYolov2; diff --git a/build/globalApi/allFaces.js b/build/globalApi/allFaces.js new file mode 100644 index 0000000..1b9f4ce --- /dev/null +++ b/build/globalApi/allFaces.js @@ -0,0 +1,11 @@ +import { TinyYolov2Options } from '../tinyYolov2'; +import { detectAllFaces } from './detectFaces'; +// export allFaces API for backward compatibility +export async function allFacesTinyYolov2(input, forwardParams = {}) { + console.warn('allFacesTinyYolov2 is deprecated and will be removed soon, use the high level api instead'); + return await detectAllFaces(input, new TinyYolov2Options(forwardParams)) + .withFaceLandmarks() + .withFaceDescriptors(); +} +export const allFaces = allFacesTinyYolov2; +//# sourceMappingURL=allFaces.js.map \ No newline at end of file diff --git a/build/globalApi/allFaces.js.map b/build/globalApi/allFaces.js.map new file mode 100644 index 0000000..3d82c09 --- /dev/null +++ b/build/globalApi/allFaces.js.map @@ -0,0 +1 @@ +{"version":3,"file":"allFaces.js","sourceRoot":"","sources":["../../src/globalApi/allFaces.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsB,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,iDAAiD;AAEjD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAgB,EAChB,gBAAoC,EAAE;IAEtC,OAAO,CAAC,IAAI,CAAC,2FAA2F,CAAC,CAAA;IACzG,OAAO,MAAM,cAAc,CAAC,KAAK,EAAE,IAAI,iBAAiB,CAAC,aAAa,CAAC,CAAC;SACrE,iBAAiB,EAAE;SACnB,mBAAmB,EAAE,CAAA;AAC1B,CAAC;AAGD,MAAM,CAAC,MAAM,QAAQ,GAAG,kBAAkB,CAAA"} \ No newline at end of file diff --git a/build/globalApi/detectFaces.d.ts b/build/globalApi/detectFaces.d.ts new file mode 100644 index 0000000..c5a3169 --- /dev/null +++ b/build/globalApi/detectFaces.d.ts @@ -0,0 +1,5 @@ +import { TNetInput } from '../dom'; +import { DetectAllFacesTask, DetectSingleFaceTask } from './DetectFacesTasks'; +import { FaceDetectionOptions } from './types'; +export declare function detectSingleFace(input: TNetInput, options?: FaceDetectionOptions): DetectSingleFaceTask; +export declare function detectAllFaces(input: TNetInput, options?: FaceDetectionOptions): DetectAllFacesTask; diff --git a/build/globalApi/detectFaces.js b/build/globalApi/detectFaces.js new file mode 100644 index 0000000..dbd971d --- /dev/null +++ b/build/globalApi/detectFaces.js @@ -0,0 +1,9 @@ +import { DetectAllFacesTask, DetectSingleFaceTask } from './DetectFacesTasks'; +import { TinyFaceDetectorOptions } from '../tinyFaceDetector/TinyFaceDetectorOptions'; +export function detectSingleFace(input, options = new TinyFaceDetectorOptions()) { + return new DetectSingleFaceTask(input, options); +} +export function detectAllFaces(input, options = new TinyFaceDetectorOptions()) { + return new DetectAllFacesTask(input, options); +} +//# sourceMappingURL=detectFaces.js.map \ No newline at end of file diff --git a/build/globalApi/detectFaces.js.map b/build/globalApi/detectFaces.js.map new file mode 100644 index 0000000..1712607 --- /dev/null +++ b/build/globalApi/detectFaces.js.map @@ -0,0 +1 @@ +{"version":3,"file":"detectFaces.js","sourceRoot":"","sources":["../../src/globalApi/detectFaces.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AAGtF,MAAM,UAAU,gBAAgB,CAC9B,KAAgB,EAChB,UAAgC,IAAI,uBAAuB,EAAE;IAE7D,OAAO,IAAI,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,KAAgB,EAChB,UAAgC,IAAI,uBAAuB,EAAE;IAE7D,OAAO,IAAI,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AAC/C,CAAC"} \ No newline at end of file diff --git a/build/globalApi/extractFacesAndComputeResults.d.ts b/build/globalApi/extractFacesAndComputeResults.d.ts new file mode 100644 index 0000000..3c6ec2c --- /dev/null +++ b/build/globalApi/extractFacesAndComputeResults.d.ts @@ -0,0 +1,7 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { FaceDetection } from '../classes/FaceDetection'; +import { TNetInput } from '../dom'; +import { WithFaceDetection } from '../factories/WithFaceDetection'; +import { WithFaceLandmarks } from '../factories/WithFaceLandmarks'; +export declare function extractAllFacesAndComputeResults, TResult>(parentResults: TSource[], input: TNetInput, computeResults: (faces: Array) => Promise, extractedFaces?: Array | null, getRectForAlignment?: (parentResult: WithFaceLandmarks) => FaceDetection): Promise; +export declare function extractSingleFaceAndComputeResult, TResult>(parentResult: TSource, input: TNetInput, computeResult: (face: HTMLCanvasElement | tf.Tensor3D) => Promise, extractedFaces?: Array | null, getRectForAlignment?: (parentResult: WithFaceLandmarks) => FaceDetection): Promise; diff --git a/build/globalApi/extractFacesAndComputeResults.js b/build/globalApi/extractFacesAndComputeResults.js new file mode 100644 index 0000000..eb045d4 --- /dev/null +++ b/build/globalApi/extractFacesAndComputeResults.js @@ -0,0 +1,18 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { extractFaces, extractFaceTensors } from '../dom'; +import { isWithFaceLandmarks } from '../factories/WithFaceLandmarks'; +export async function extractAllFacesAndComputeResults(parentResults, input, computeResults, extractedFaces, getRectForAlignment = ({ alignedRect }) => alignedRect) { + const faceBoxes = parentResults.map(parentResult => isWithFaceLandmarks(parentResult) + ? getRectForAlignment(parentResult) + : parentResult.detection); + const faces = extractedFaces || (input instanceof tf.Tensor + ? await extractFaceTensors(input, faceBoxes) + : await extractFaces(input, faceBoxes)); + const results = await computeResults(faces); + faces.forEach(f => f instanceof tf.Tensor && f.dispose()); + return results; +} +export async function extractSingleFaceAndComputeResult(parentResult, input, computeResult, extractedFaces, getRectForAlignment) { + return extractAllFacesAndComputeResults([parentResult], input, async (faces) => computeResult(faces[0]), extractedFaces, getRectForAlignment); +} +//# sourceMappingURL=extractFacesAndComputeResults.js.map \ No newline at end of file diff --git a/build/globalApi/extractFacesAndComputeResults.js.map b/build/globalApi/extractFacesAndComputeResults.js.map new file mode 100644 index 0000000..533fa02 --- /dev/null +++ b/build/globalApi/extractFacesAndComputeResults.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractFacesAndComputeResults.js","sourceRoot":"","sources":["../../src/globalApi/extractFacesAndComputeResults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAG5C,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAa,MAAM,QAAQ,CAAC;AAErE,OAAO,EAAE,mBAAmB,EAAqB,MAAM,gCAAgC,CAAC;AAExF,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,aAAwB,EACxB,KAAgB,EAChB,cAAmF,EACnF,cAA8D,EAC9D,sBAAwF,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,WAAW;IAExH,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CACjD,mBAAmB,CAAC,YAAY,CAAC;QAC/B,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC;QACnC,CAAC,CAAC,YAAY,CAAC,SAAS,CAC3B,CAAA;IACD,MAAM,KAAK,GAA2C,cAAc,IAAI,CACtE,KAAK,YAAY,EAAE,CAAC,MAAM;QACxB,CAAC,CAAC,MAAM,kBAAkB,CAAC,KAAK,EAAE,SAAS,CAAC;QAC5C,CAAC,CAAC,MAAM,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CACzC,CAAA;IAED,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,CAAA;IAE3C,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IAEzD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,YAAqB,EACrB,KAAgB,EAChB,aAA0E,EAC1E,cAA8D,EAC9D,mBAAsF;IAEtF,OAAO,gCAAgC,CACrC,CAAC,YAAY,CAAC,EACd,KAAK,EACL,KAAK,EAAC,KAAK,EAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EACtC,cAAc,EACd,mBAAmB,CACpB,CAAA;AACH,CAAC"} \ No newline at end of file diff --git a/build/globalApi/index.d.ts b/build/globalApi/index.d.ts new file mode 100644 index 0000000..5453caa --- /dev/null +++ b/build/globalApi/index.d.ts @@ -0,0 +1,8 @@ +export * from './ComposableTask'; +export * from './ComputeFaceDescriptorsTasks'; +export * from './detectFaces'; +export * from './DetectFacesTasks'; +export * from './DetectFaceLandmarksTasks'; +export * from './FaceMatcher'; +export * from './nets'; +export * from './types'; diff --git a/build/globalApi/index.js b/build/globalApi/index.js new file mode 100644 index 0000000..78d179a --- /dev/null +++ b/build/globalApi/index.js @@ -0,0 +1,9 @@ +export * from './ComposableTask'; +export * from './ComputeFaceDescriptorsTasks'; +export * from './detectFaces'; +export * from './DetectFacesTasks'; +export * from './DetectFaceLandmarksTasks'; +export * from './FaceMatcher'; +export * from './nets'; +export * from './types'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/globalApi/index.js.map b/build/globalApi/index.js.map new file mode 100644 index 0000000..8efdbf7 --- /dev/null +++ b/build/globalApi/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/globalApi/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,eAAe,CAAA;AAC7B,cAAc,oBAAoB,CAAA;AAClC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,eAAe,CAAA;AAC7B,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA"} \ No newline at end of file diff --git a/build/globalApi/nets.d.ts b/build/globalApi/nets.d.ts new file mode 100644 index 0000000..174d567 --- /dev/null +++ b/build/globalApi/nets.d.ts @@ -0,0 +1,85 @@ +import { AgeGenderNet } from '../ageGenderNet/AgeGenderNet'; +import { AgeAndGenderPrediction } from '../ageGenderNet/types'; +import { FaceDetection } from '../classes/FaceDetection'; +import { FaceLandmarks68 } from '../classes/FaceLandmarks68'; +import { TNetInput } from '../dom'; +import { FaceExpressionNet } from '../faceExpressionNet/FaceExpressionNet'; +import { FaceExpressions } from '../faceExpressionNet/FaceExpressions'; +import { FaceLandmark68Net } from '../faceLandmarkNet/FaceLandmark68Net'; +import { FaceLandmark68TinyNet } from '../faceLandmarkNet/FaceLandmark68TinyNet'; +import { FaceRecognitionNet } from '../faceRecognitionNet/FaceRecognitionNet'; +import { TinyFaceDetector } from '../tinyFaceDetector/TinyFaceDetector'; +import { TinyFaceDetectorOptions } from '../tinyFaceDetector/TinyFaceDetectorOptions'; +import { TinyYolov2 } from '../tinyYolov2'; +export declare const nets: { + tinyFaceDetector: TinyFaceDetector; + tinyYolov2: TinyYolov2; + faceLandmark68Net: FaceLandmark68Net; + faceLandmark68TinyNet: FaceLandmark68TinyNet; + faceRecognitionNet: FaceRecognitionNet; + faceExpressionNet: FaceExpressionNet; + ageGenderNet: AgeGenderNet; +}; +/** + * Attempts to detect all faces in an image using the Tiny Face Detector. + * + * @param input The input image. + * @param options (optional, default: see TinyFaceDetectorOptions constructor for default parameters). + * @returns Bounding box of each face with score. + */ +export declare const tinyFaceDetector: (input: TNetInput, options: TinyFaceDetectorOptions) => Promise; +/** + * Detects the 68 point face landmark positions of the face shown in an image. + * + * @param inputs The face image extracted from the bounding box of a face. Can + * also be an array of input images, which will be batch processed. + * @returns 68 point face landmarks or array thereof in case of batch input. + */ +export declare const detectFaceLandmarks: (input: TNetInput) => Promise; +/** + * Detects the 68 point face landmark positions of the face shown in an image + * using a tinier version of the 68 point face landmark model, which is slightly + * faster at inference, but also slightly less accurate. + * + * @param inputs The face image extracted from the bounding box of a face. Can + * also be an array of input images, which will be batch processed. + * @returns 68 point face landmarks or array thereof in case of batch input. + */ +export declare const detectFaceLandmarksTiny: (input: TNetInput) => Promise; +/** + * Computes a 128 entry vector (face descriptor / face embeddings) from the face shown in an image, + * which uniquely represents the features of that persons face. The computed face descriptor can + * be used to measure the similarity between faces, by computing the euclidean distance of two + * face descriptors. + * + * @param inputs The face image extracted from the aligned bounding box of a face. Can + * also be an array of input images, which will be batch processed. + * @returns Face descriptor with 128 entries or array thereof in case of batch input. + */ +export declare const computeFaceDescriptor: (input: TNetInput) => Promise; +/** + * Recognizes the facial expressions from a face image. + * + * @param inputs The face image extracted from the bounding box of a face. Can + * also be an array of input images, which will be batch processed. + * @returns Facial expressions with corresponding probabilities or array thereof in case of batch input. + */ +export declare const recognizeFaceExpressions: (input: TNetInput) => Promise; +/** + * Predicts age and gender from a face image. + * + * @param inputs The face image extracted from the bounding box of a face. Can + * also be an array of input images, which will be batch processed. + * @returns Predictions with age, gender and gender probability or array thereof in case of batch input. + */ +export declare const predictAgeAndGender: (input: TNetInput) => Promise; +export declare const loadTinyFaceDetectorModel: (url: string) => Promise; +export declare const loadTinyYolov2Model: (url: string) => Promise; +export declare const loadFaceLandmarkModel: (url: string) => Promise; +export declare const loadFaceLandmarkTinyModel: (url: string) => Promise; +export declare const loadFaceRecognitionModel: (url: string) => Promise; +export declare const loadFaceExpressionModel: (url: string) => Promise; +export declare const loadAgeGenderModel: (url: string) => Promise; +export declare const loadFaceDetectionModel: (url: string) => Promise; +export declare const locateFaces: typeof TinyFaceDetector; +export declare const detectLandmarks: (input: TNetInput) => Promise; diff --git a/build/globalApi/nets.js b/build/globalApi/nets.js new file mode 100644 index 0000000..668e68f --- /dev/null +++ b/build/globalApi/nets.js @@ -0,0 +1,81 @@ +import { AgeGenderNet } from '../ageGenderNet/AgeGenderNet'; +import { FaceExpressionNet } from '../faceExpressionNet/FaceExpressionNet'; +import { FaceLandmark68Net } from '../faceLandmarkNet/FaceLandmark68Net'; +import { FaceLandmark68TinyNet } from '../faceLandmarkNet/FaceLandmark68TinyNet'; +import { FaceRecognitionNet } from '../faceRecognitionNet/FaceRecognitionNet'; +import { TinyFaceDetector } from '../tinyFaceDetector/TinyFaceDetector'; +import { TinyYolov2 } from '../tinyYolov2'; +export const nets = { + tinyFaceDetector: new TinyFaceDetector(), + tinyYolov2: new TinyYolov2(), + faceLandmark68Net: new FaceLandmark68Net(), + faceLandmark68TinyNet: new FaceLandmark68TinyNet(), + faceRecognitionNet: new FaceRecognitionNet(), + faceExpressionNet: new FaceExpressionNet(), + ageGenderNet: new AgeGenderNet() +}; +/** + * Attempts to detect all faces in an image using the Tiny Face Detector. + * + * @param input The input image. + * @param options (optional, default: see TinyFaceDetectorOptions constructor for default parameters). + * @returns Bounding box of each face with score. + */ +export const tinyFaceDetector = (input, options) => nets.tinyFaceDetector.locateFaces(input, options); +/** + * Detects the 68 point face landmark positions of the face shown in an image. + * + * @param inputs The face image extracted from the bounding box of a face. Can + * also be an array of input images, which will be batch processed. + * @returns 68 point face landmarks or array thereof in case of batch input. + */ +export const detectFaceLandmarks = (input) => nets.faceLandmark68Net.detectLandmarks(input); +/** + * Detects the 68 point face landmark positions of the face shown in an image + * using a tinier version of the 68 point face landmark model, which is slightly + * faster at inference, but also slightly less accurate. + * + * @param inputs The face image extracted from the bounding box of a face. Can + * also be an array of input images, which will be batch processed. + * @returns 68 point face landmarks or array thereof in case of batch input. + */ +export const detectFaceLandmarksTiny = (input) => nets.faceLandmark68TinyNet.detectLandmarks(input); +/** + * Computes a 128 entry vector (face descriptor / face embeddings) from the face shown in an image, + * which uniquely represents the features of that persons face. The computed face descriptor can + * be used to measure the similarity between faces, by computing the euclidean distance of two + * face descriptors. + * + * @param inputs The face image extracted from the aligned bounding box of a face. Can + * also be an array of input images, which will be batch processed. + * @returns Face descriptor with 128 entries or array thereof in case of batch input. + */ +export const computeFaceDescriptor = (input) => nets.faceRecognitionNet.computeFaceDescriptor(input); +/** + * Recognizes the facial expressions from a face image. + * + * @param inputs The face image extracted from the bounding box of a face. Can + * also be an array of input images, which will be batch processed. + * @returns Facial expressions with corresponding probabilities or array thereof in case of batch input. + */ +export const recognizeFaceExpressions = (input) => nets.faceExpressionNet.predictExpressions(input); +/** + * Predicts age and gender from a face image. + * + * @param inputs The face image extracted from the bounding box of a face. Can + * also be an array of input images, which will be batch processed. + * @returns Predictions with age, gender and gender probability or array thereof in case of batch input. + */ +export const predictAgeAndGender = (input) => nets.ageGenderNet.predictAgeAndGender(input); +export const loadTinyFaceDetectorModel = (url) => nets.tinyFaceDetector.load(url); +export const loadTinyYolov2Model = (url) => nets.tinyYolov2.load(url); +export const loadFaceLandmarkModel = (url) => nets.faceLandmark68Net.load(url); +export const loadFaceLandmarkTinyModel = (url) => nets.faceLandmark68TinyNet.load(url); +export const loadFaceRecognitionModel = (url) => nets.faceRecognitionNet.load(url); +export const loadFaceExpressionModel = (url) => nets.faceExpressionNet.load(url); +export const loadAgeGenderModel = (url) => nets.ageGenderNet.load(url); +// backward compatibility +export const loadFaceDetectionModel = loadTinyFaceDetectorModel; +export const locateFaces = TinyFaceDetector; +export const detectLandmarks = detectFaceLandmarks; +//# sourceMappingURL=nets.js.map \ No newline at end of file diff --git a/build/globalApi/nets.js.map b/build/globalApi/nets.js.map new file mode 100644 index 0000000..b36b653 --- /dev/null +++ b/build/globalApi/nets.js.map @@ -0,0 +1 @@ +{"version":3,"file":"nets.js","sourceRoot":"","sources":["../../src/globalApi/nets.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/globalApi/types.d.ts b/build/globalApi/types.d.ts new file mode 100644 index 0000000..e4e3afa --- /dev/null +++ b/build/globalApi/types.d.ts @@ -0,0 +1,5 @@ +import { FaceDetection } from '../classes/FaceDetection'; +import { TNetInput } from '../dom'; +import { TinyFaceDetectorOptions } from '../tinyFaceDetector/TinyFaceDetectorOptions'; +export declare type FaceDetectionOptions = TinyFaceDetectorOptions; +export declare type FaceDetectionFunction = (input: TNetInput) => Promise; diff --git a/build/globalApi/types.js b/build/globalApi/types.js new file mode 100644 index 0000000..5b2306a --- /dev/null +++ b/build/globalApi/types.js @@ -0,0 +1 @@ +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/build/globalApi/types.js.map b/build/globalApi/types.js.map new file mode 100644 index 0000000..1473b90 --- /dev/null +++ b/build/globalApi/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/globalApi/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/index.d.ts b/build/index.d.ts new file mode 100644 index 0000000..8db682b --- /dev/null +++ b/build/index.d.ts @@ -0,0 +1,19 @@ +import * as tf from '@tensorflow/tfjs-core'; +import * as draw from './draw'; +import * as utils from './utils'; +export { draw, utils, tf }; +export * from './ageGenderNet/index'; +export * from './classes/index'; +export * from './dom/index'; +export * from './env/index'; +export * from './faceExpressionNet/index'; +export * from './faceLandmarkNet/index'; +export * from './faceRecognitionNet/index'; +export * from './factories/index'; +export * from './globalApi/index'; +export * from './ops/index'; +export * from './tinyFaceDetector/index'; +export * from './tinyYolov2/index'; +export * from './euclideanDistance'; +export * from './NeuralNetwork'; +export * from './resizeResults'; diff --git a/build/index.js b/build/index.js new file mode 100644 index 0000000..4bb9001 --- /dev/null +++ b/build/index.js @@ -0,0 +1,20 @@ +import * as tf from '@tensorflow/tfjs-core'; +import * as draw from './draw'; +import * as utils from './utils'; +export { draw, utils, tf }; +export * from './ageGenderNet/index'; +export * from './classes/index'; +export * from './dom/index'; +export * from './env/index'; +export * from './faceExpressionNet/index'; +export * from './faceLandmarkNet/index'; +export * from './faceRecognitionNet/index'; +export * from './factories/index'; +export * from './globalApi/index'; +export * from './ops/index'; +export * from './tinyFaceDetector/index'; +export * from './tinyYolov2/index'; +export * from './euclideanDistance'; +export * from './NeuralNetwork'; +export * from './resizeResults'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/index.js.map b/build/index.js.map new file mode 100644 index 0000000..1dcda04 --- /dev/null +++ b/build/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAEjC,OAAO,EACL,IAAI,EACJ,KAAK,EACL,EAAE,EACH,CAAA;AAED,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AAEnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC"} \ No newline at end of file diff --git a/build/ops/index.d.ts b/build/ops/index.d.ts new file mode 100644 index 0000000..825d345 --- /dev/null +++ b/build/ops/index.d.ts @@ -0,0 +1,8 @@ +export * from './iou'; +export * from './minBbox'; +export * from './nonMaxSuppression'; +export * from './normalize'; +export * from './padToSquare'; +export * from './shuffleArray'; +export declare function sigmoid(x: number): number; +export declare function inverseSigmoid(x: number): number; diff --git a/build/ops/index.js b/build/ops/index.js new file mode 100644 index 0000000..5b45757 --- /dev/null +++ b/build/ops/index.js @@ -0,0 +1,13 @@ +export * from './iou'; +export * from './minBbox'; +export * from './nonMaxSuppression'; +export * from './normalize'; +export * from './padToSquare'; +export * from './shuffleArray'; +export function sigmoid(x) { + return 1 / (1 + Math.exp(-x)); +} +export function inverseSigmoid(x) { + return Math.log(x / (1 - x)); +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/ops/index.js.map b/build/ops/index.js.map new file mode 100644 index 0000000..e84f6cf --- /dev/null +++ b/build/ops/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ops/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAA;AACrB,cAAc,WAAW,CAAA;AACzB,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAE9B,MAAM,UAAU,OAAO,CAAC,CAAS;IAC/B,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAC9B,CAAC"} \ No newline at end of file diff --git a/build/ops/iou.d.ts b/build/ops/iou.d.ts new file mode 100644 index 0000000..0e800d7 --- /dev/null +++ b/build/ops/iou.d.ts @@ -0,0 +1,2 @@ +import { Box } from '../classes/Box'; +export declare function iou(box1: Box, box2: Box, isIOU?: boolean): number; diff --git a/build/ops/iou.js b/build/ops/iou.js new file mode 100644 index 0000000..bcbec9d --- /dev/null +++ b/build/ops/iou.js @@ -0,0 +1,9 @@ +export function iou(box1, box2, isIOU = true) { + const width = Math.max(0.0, Math.min(box1.right, box2.right) - Math.max(box1.left, box2.left)); + const height = Math.max(0.0, Math.min(box1.bottom, box2.bottom) - Math.max(box1.top, box2.top)); + const interSection = width * height; + return isIOU + ? interSection / (box1.area + box2.area - interSection) + : interSection / Math.min(box1.area, box2.area); +} +//# sourceMappingURL=iou.js.map \ No newline at end of file diff --git a/build/ops/iou.js.map b/build/ops/iou.js.map new file mode 100644 index 0000000..216a7dd --- /dev/null +++ b/build/ops/iou.js.map @@ -0,0 +1 @@ +{"version":3,"file":"iou.js","sourceRoot":"","sources":["../../src/ops/iou.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAG,CAAC,IAAS,EAAE,IAAS,EAAE,QAAiB,IAAI;IAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC9F,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IAC/F,MAAM,YAAY,GAAG,KAAK,GAAG,MAAM,CAAA;IAEnC,OAAO,KAAK;QACV,CAAC,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACvD,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;AACnD,CAAC"} \ No newline at end of file diff --git a/build/ops/minBbox.d.ts b/build/ops/minBbox.d.ts new file mode 100644 index 0000000..37e1358 --- /dev/null +++ b/build/ops/minBbox.d.ts @@ -0,0 +1,2 @@ +import { BoundingBox, IPoint } from '../classes'; +export declare function minBbox(pts: IPoint[]): BoundingBox; diff --git a/build/ops/minBbox.js b/build/ops/minBbox.js new file mode 100644 index 0000000..e7915e3 --- /dev/null +++ b/build/ops/minBbox.js @@ -0,0 +1,11 @@ +import { BoundingBox } from '../classes'; +export function minBbox(pts) { + const xs = pts.map(pt => pt.x); + const ys = pts.map(pt => pt.y); + const minX = xs.reduce((min, x) => x < min ? x : min, Infinity); + const minY = ys.reduce((min, y) => y < min ? y : min, Infinity); + const maxX = xs.reduce((max, x) => max < x ? x : max, 0); + const maxY = ys.reduce((max, y) => max < y ? y : max, 0); + return new BoundingBox(minX, minY, maxX, maxY); +} +//# sourceMappingURL=minBbox.js.map \ No newline at end of file diff --git a/build/ops/minBbox.js.map b/build/ops/minBbox.js.map new file mode 100644 index 0000000..5ae1a06 --- /dev/null +++ b/build/ops/minBbox.js.map @@ -0,0 +1 @@ +{"version":3,"file":"minBbox.js","sourceRoot":"","sources":["../../src/ops/minBbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAU,MAAM,YAAY,CAAC;AAEjD,MAAM,UAAU,OAAO,CAAC,GAAa;IACnC,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC9B,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC9B,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;IAC/D,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;IAC/D,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IACxD,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAExD,OAAO,IAAI,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;AAChD,CAAC"} \ No newline at end of file diff --git a/build/ops/nonMaxSuppression.d.ts b/build/ops/nonMaxSuppression.d.ts new file mode 100644 index 0000000..bba434a --- /dev/null +++ b/build/ops/nonMaxSuppression.d.ts @@ -0,0 +1,2 @@ +import { Box } from '../classes/Box'; +export declare function nonMaxSuppression(boxes: Box[], scores: number[], iouThreshold: number, isIOU?: boolean): number[]; diff --git a/build/ops/nonMaxSuppression.js b/build/ops/nonMaxSuppression.js new file mode 100644 index 0000000..05ded75 --- /dev/null +++ b/build/ops/nonMaxSuppression.js @@ -0,0 +1,23 @@ +import { iou } from './iou'; +export function nonMaxSuppression(boxes, scores, iouThreshold, isIOU = true) { + let indicesSortedByScore = scores + .map((score, boxIndex) => ({ score, boxIndex })) + .sort((c1, c2) => c1.score - c2.score) + .map(c => c.boxIndex); + const pick = []; + while (indicesSortedByScore.length > 0) { + const curr = indicesSortedByScore.pop(); + pick.push(curr); + const indices = indicesSortedByScore; + const outputs = []; + for (let i = 0; i < indices.length; i++) { + const idx = indices[i]; + const currBox = boxes[curr]; + const idxBox = boxes[idx]; + outputs.push(iou(currBox, idxBox, isIOU)); + } + indicesSortedByScore = indicesSortedByScore.filter((_, j) => outputs[j] <= iouThreshold); + } + return pick; +} +//# sourceMappingURL=nonMaxSuppression.js.map \ No newline at end of file diff --git a/build/ops/nonMaxSuppression.js.map b/build/ops/nonMaxSuppression.js.map new file mode 100644 index 0000000..24abc7c --- /dev/null +++ b/build/ops/nonMaxSuppression.js.map @@ -0,0 +1 @@ +{"version":3,"file":"nonMaxSuppression.js","sourceRoot":"","sources":["../../src/ops/nonMaxSuppression.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAE5B,MAAM,UAAU,iBAAiB,CAC/B,KAAY,EACZ,MAAgB,EAChB,YAAoB,EACpB,QAAiB,IAAI;IAGrB,IAAI,oBAAoB,GAAG,MAAM;SAC9B,GAAG,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;SAC/C,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC;SACrC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;IAEvB,MAAM,IAAI,GAAa,EAAE,CAAA;IAEzB,OAAM,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE;QACrC,MAAM,IAAI,GAAG,oBAAoB,CAAC,GAAG,EAAY,CAAA;QACjD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEf,MAAM,OAAO,GAAG,oBAAoB,CAAA;QAEpC,MAAM,OAAO,GAAa,EAAE,CAAA;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACvC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;YAEtB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;YAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;YAEzB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;SAC1C;QAED,oBAAoB,GAAG,oBAAoB,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,YAAY,CACrC,CAAA;KACF;IAED,OAAO,IAAI,CAAA;AAEb,CAAC"} \ No newline at end of file diff --git a/build/ops/normalize.d.ts b/build/ops/normalize.d.ts new file mode 100644 index 0000000..10cc558 --- /dev/null +++ b/build/ops/normalize.d.ts @@ -0,0 +1,2 @@ +import * as tf from '@tensorflow/tfjs-core'; +export declare function normalize(x: tf.Tensor4D, meanRgb: number[]): tf.Tensor4D; diff --git a/build/ops/normalize.js b/build/ops/normalize.js new file mode 100644 index 0000000..e489c02 --- /dev/null +++ b/build/ops/normalize.js @@ -0,0 +1,12 @@ +import * as tf from '@tensorflow/tfjs-core'; +export function normalize(x, meanRgb) { + return tf.tidy(() => { + const [r, g, b] = meanRgb; + const avg_r = tf.fill([...x.shape.slice(0, 3), 1], r); + const avg_g = tf.fill([...x.shape.slice(0, 3), 1], g); + const avg_b = tf.fill([...x.shape.slice(0, 3), 1], b); + const avg_rgb = tf.concat([avg_r, avg_g, avg_b], 3); + return tf.sub(x, avg_rgb); + }); +} +//# sourceMappingURL=normalize.js.map \ No newline at end of file diff --git a/build/ops/normalize.js.map b/build/ops/normalize.js.map new file mode 100644 index 0000000..a0c8650 --- /dev/null +++ b/build/ops/normalize.js.map @@ -0,0 +1 @@ +{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/ops/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,MAAM,UAAU,SAAS,CAAC,CAAc,EAAE,OAAiB;IACzD,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QAClB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAA;QACzB,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QACrD,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QACrD,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QACrD,MAAM,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;QAEnD,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/ops/padToSquare.d.ts b/build/ops/padToSquare.d.ts new file mode 100644 index 0000000..3322894 --- /dev/null +++ b/build/ops/padToSquare.d.ts @@ -0,0 +1,10 @@ +import * as tf from '@tensorflow/tfjs-core'; +/** + * Pads the smaller dimension of an image tensor with zeros, such that width === height. + * + * @param imgTensor The image tensor. + * @param isCenterImage (optional, default: false) If true, add an equal amount of padding on + * both sides of the minor dimension oof the image. + * @returns The padded tensor with width === height. + */ +export declare function padToSquare(imgTensor: tf.Tensor4D, isCenterImage?: boolean): tf.Tensor4D; diff --git a/build/ops/padToSquare.js b/build/ops/padToSquare.js new file mode 100644 index 0000000..ca4d024 --- /dev/null +++ b/build/ops/padToSquare.js @@ -0,0 +1,39 @@ +import * as tf from '@tensorflow/tfjs-core'; +/** + * Pads the smaller dimension of an image tensor with zeros, such that width === height. + * + * @param imgTensor The image tensor. + * @param isCenterImage (optional, default: false) If true, add an equal amount of padding on + * both sides of the minor dimension oof the image. + * @returns The padded tensor with width === height. + */ +export function padToSquare(imgTensor, isCenterImage = false) { + return tf.tidy(() => { + const [height, width] = imgTensor.shape.slice(1); + if (height === width) { + return imgTensor; + } + const dimDiff = Math.abs(height - width); + const paddingAmount = Math.round(dimDiff * (isCenterImage ? 0.5 : 1)); + const paddingAxis = height > width ? 2 : 1; + const createPaddingTensor = (paddingAmount) => { + const paddingTensorShape = imgTensor.shape.slice(); + paddingTensorShape[paddingAxis] = paddingAmount; + return tf.fill(paddingTensorShape, 0); + }; + const paddingTensorAppend = createPaddingTensor(paddingAmount); + const remainingPaddingAmount = dimDiff - paddingTensorAppend.shape[paddingAxis]; + const paddingTensorPrepend = isCenterImage && remainingPaddingAmount + ? createPaddingTensor(remainingPaddingAmount) + : null; + const tensorsToStack = [ + paddingTensorPrepend, + imgTensor, + paddingTensorAppend + ] + .filter(t => !!t) + .map((t) => t.toFloat()); + return tf.concat(tensorsToStack, paddingAxis); + }); +} +//# sourceMappingURL=padToSquare.js.map \ No newline at end of file diff --git a/build/ops/padToSquare.js.map b/build/ops/padToSquare.js.map new file mode 100644 index 0000000..32b423e --- /dev/null +++ b/build/ops/padToSquare.js.map @@ -0,0 +1 @@ +{"version":3,"file":"padToSquare.js","sourceRoot":"","sources":["../../src/ops/padToSquare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CACzB,SAAsB,EACtB,gBAAyB,KAAK;IAE9B,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QAElB,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAChD,IAAI,MAAM,KAAK,KAAK,EAAE;YACpB,OAAO,SAAS,CAAA;SACjB;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAA;QACxC,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACrE,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAE1C,MAAM,mBAAmB,GAAG,CAAC,aAAqB,EAAa,EAAE;YAC/D,MAAM,kBAAkB,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;YAClD,kBAAkB,CAAC,WAAW,CAAC,GAAG,aAAa,CAAA;YAC/C,OAAO,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAA;QACvC,CAAC,CAAA;QAED,MAAM,mBAAmB,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAA;QAC9D,MAAM,sBAAsB,GAAG,OAAO,GAAI,mBAAmB,CAAC,KAAK,CAAC,WAAW,CAAY,CAAA;QAE3F,MAAM,oBAAoB,GAAG,aAAa,IAAI,sBAAsB;YAClE,CAAC,CAAC,mBAAmB,CAAC,sBAAsB,CAAC;YAC7C,CAAC,CAAC,IAAI,CAAA;QAER,MAAM,cAAc,GAAG;YACrB,oBAAoB;YACpB,SAAS;YACT,mBAAmB;SACpB;aACE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;aAChB,GAAG,CAAC,CAAC,CAAY,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAkB,CAAA;QACtD,OAAO,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/ops/shuffleArray.d.ts b/build/ops/shuffleArray.d.ts new file mode 100644 index 0000000..2783fec --- /dev/null +++ b/build/ops/shuffleArray.d.ts @@ -0,0 +1 @@ +export declare function shuffleArray(inputArray: any[]): any[]; diff --git a/build/ops/shuffleArray.js b/build/ops/shuffleArray.js new file mode 100644 index 0000000..e9baaa0 --- /dev/null +++ b/build/ops/shuffleArray.js @@ -0,0 +1,11 @@ +export function shuffleArray(inputArray) { + const array = inputArray.slice(); + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + const x = array[i]; + array[i] = array[j]; + array[j] = x; + } + return array; +} +//# sourceMappingURL=shuffleArray.js.map \ No newline at end of file diff --git a/build/ops/shuffleArray.js.map b/build/ops/shuffleArray.js.map new file mode 100644 index 0000000..5a50a75 --- /dev/null +++ b/build/ops/shuffleArray.js.map @@ -0,0 +1 @@ +{"version":3,"file":"shuffleArray.js","sourceRoot":"","sources":["../../src/ops/shuffleArray.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,UAAiB;IAC5C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,CAAA;IAChC,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QAC7C,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QAClB,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACnB,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;KACf;IACD,OAAO,KAAK,CAAA;AACd,CAAC"} \ No newline at end of file diff --git a/build/resizeResults.d.ts b/build/resizeResults.d.ts new file mode 100644 index 0000000..3910d16 --- /dev/null +++ b/build/resizeResults.d.ts @@ -0,0 +1,2 @@ +import { IDimensions } from './classes'; +export declare function resizeResults(results: T, dimensions: IDimensions): T; diff --git a/build/resizeResults.js b/build/resizeResults.js new file mode 100644 index 0000000..2d5ec8a --- /dev/null +++ b/build/resizeResults.js @@ -0,0 +1,27 @@ +import { Dimensions } from './classes'; +import { FaceDetection } from './classes/FaceDetection'; +import { FaceLandmarks } from './classes/FaceLandmarks'; +import { extendWithFaceDetection, isWithFaceDetection } from './factories/WithFaceDetection'; +import { extendWithFaceLandmarks, isWithFaceLandmarks } from './factories/WithFaceLandmarks'; +export function resizeResults(results, dimensions) { + const { width, height } = new Dimensions(dimensions.width, dimensions.height); + if (width <= 0 || height <= 0) { + throw new Error(`resizeResults - invalid dimensions: ${JSON.stringify({ width, height })}`); + } + if (Array.isArray(results)) { + return results.map(obj => resizeResults(obj, { width, height })); + } + if (isWithFaceLandmarks(results)) { + const resizedDetection = results.detection.forSize(width, height); + const resizedLandmarks = results.unshiftedLandmarks.forSize(resizedDetection.box.width, resizedDetection.box.height); + return extendWithFaceLandmarks(extendWithFaceDetection(results, resizedDetection), resizedLandmarks); + } + if (isWithFaceDetection(results)) { + return extendWithFaceDetection(results, results.detection.forSize(width, height)); + } + if (results instanceof FaceLandmarks || results instanceof FaceDetection) { + return results.forSize(width, height); + } + return results; +} +//# sourceMappingURL=resizeResults.js.map \ No newline at end of file diff --git a/build/resizeResults.js.map b/build/resizeResults.js.map new file mode 100644 index 0000000..4278f2d --- /dev/null +++ b/build/resizeResults.js.map @@ -0,0 +1 @@ +{"version":3,"file":"resizeResults.js","sourceRoot":"","sources":["../src/resizeResults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAe,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAE7F,MAAM,UAAU,aAAa,CAAI,OAAU,EAAE,UAAuB;IAElE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;IAE7E,IAAI,KAAK,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE;QAC7B,MAAM,IAAI,KAAK,CAAC,uCAAuC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAA;KAC5F;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAa,CAAA;KAC7E;IAED,IAAI,mBAAmB,CAAC,OAAO,CAAC,EAAE;QAChC,MAAM,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACjE,MAAM,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAEpH,OAAO,uBAAuB,CAAC,uBAAuB,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,CAAA;KACrG;IAED,IAAI,mBAAmB,CAAC,OAAO,CAAC,EAAE;QAChC,OAAO,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;KAClF;IAED,IAAI,OAAO,YAAY,aAAa,IAAI,OAAO,YAAY,aAAa,EAAE;QACxE,OAAQ,OAAe,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;KAC/C;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"} \ No newline at end of file diff --git a/build/tinyFaceDetector/TinyFaceDetector.d.ts b/build/tinyFaceDetector/TinyFaceDetector.d.ts new file mode 100644 index 0000000..e114768 --- /dev/null +++ b/build/tinyFaceDetector/TinyFaceDetector.d.ts @@ -0,0 +1,17 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { FaceDetection, Point } from '../classes'; +import { ParamMapping } from '../common'; +import { TNetInput } from '../dom'; +import { ITinyYolov2Options } from '../tinyYolov2'; +import { TinyYolov2Base } from '../tinyYolov2/TinyYolov2Base'; +import { TinyYolov2NetParams } from '../tinyYolov2/types'; +export declare class TinyFaceDetector extends TinyYolov2Base { + constructor(); + get anchors(): Point[]; + locateFaces(input: TNetInput, forwardParams: ITinyYolov2Options): Promise; + protected getDefaultModelName(): string; + protected extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap): { + params: TinyYolov2NetParams; + paramMappings: ParamMapping[]; + }; +} diff --git a/build/tinyFaceDetector/TinyFaceDetector.js b/build/tinyFaceDetector/TinyFaceDetector.js new file mode 100644 index 0000000..9024d31 --- /dev/null +++ b/build/tinyFaceDetector/TinyFaceDetector.js @@ -0,0 +1,31 @@ +import { FaceDetection } from '../classes'; +import { TinyYolov2Base } from '../tinyYolov2/TinyYolov2Base'; +import { BOX_ANCHORS, IOU_THRESHOLD, MEAN_RGB } from './const'; +export class TinyFaceDetector extends TinyYolov2Base { + constructor() { + const config = { + withSeparableConvs: true, + iouThreshold: IOU_THRESHOLD, + classes: ['face'], + anchors: BOX_ANCHORS, + meanRgb: MEAN_RGB, + isFirstLayerConv2d: true, + filterSizes: [3, 16, 32, 64, 128, 256, 512] + }; + super(config); + } + get anchors() { + return this.config.anchors; + } + async locateFaces(input, forwardParams) { + const objectDetections = await this.detect(input, forwardParams); + return objectDetections.map(det => new FaceDetection(det.score, det.relativeBox, { width: det.imageWidth, height: det.imageHeight })); + } + getDefaultModelName() { + return 'tiny_face_detector_model'; + } + extractParamsFromWeigthMap(weightMap) { + return super.extractParamsFromWeigthMap(weightMap); + } +} +//# sourceMappingURL=TinyFaceDetector.js.map \ No newline at end of file diff --git a/build/tinyFaceDetector/TinyFaceDetector.js.map b/build/tinyFaceDetector/TinyFaceDetector.js.map new file mode 100644 index 0000000..0e3f274 --- /dev/null +++ b/build/tinyFaceDetector/TinyFaceDetector.js.map @@ -0,0 +1 @@ +{"version":3,"file":"TinyFaceDetector.js","sourceRoot":"","sources":["../../src/tinyFaceDetector/TinyFaceDetector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAS,MAAM,YAAY,CAAC;AAIlD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE/D,MAAM,OAAO,gBAAiB,SAAQ,cAAc;IAElD;QACE,MAAM,MAAM,GAAG;YACb,kBAAkB,EAAE,IAAI;YACxB,YAAY,EAAE,aAAa;YAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;YACjB,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,QAAQ;YACjB,kBAAkB,EAAE,IAAI;YACxB,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;SAC5C,CAAA;QAED,KAAK,CAAC,MAAM,CAAC,CAAA;IACf,CAAC;IAED,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,KAAgB,EAAE,aAAiC;QAC1E,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,CAAA;QAChE,OAAO,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;IACvI,CAAC;IAES,mBAAmB;QAC3B,OAAO,0BAA0B,CAAA;IACnC,CAAC;IAES,0BAA0B,CAAC,SAA4B;QAC/D,OAAO,KAAK,CAAC,0BAA0B,CAAC,SAAS,CAAC,CAAA;IACpD,CAAC;CACF"} \ No newline at end of file diff --git a/build/tinyFaceDetector/TinyFaceDetectorOptions.d.ts b/build/tinyFaceDetector/TinyFaceDetectorOptions.d.ts new file mode 100644 index 0000000..8730ed7 --- /dev/null +++ b/build/tinyFaceDetector/TinyFaceDetectorOptions.d.ts @@ -0,0 +1,6 @@ +import { ITinyYolov2Options, TinyYolov2Options } from '../tinyYolov2'; +export interface ITinyFaceDetectorOptions extends ITinyYolov2Options { +} +export declare class TinyFaceDetectorOptions extends TinyYolov2Options { + protected _name: string; +} diff --git a/build/tinyFaceDetector/TinyFaceDetectorOptions.js b/build/tinyFaceDetector/TinyFaceDetectorOptions.js new file mode 100644 index 0000000..53d6172 --- /dev/null +++ b/build/tinyFaceDetector/TinyFaceDetectorOptions.js @@ -0,0 +1,8 @@ +import { TinyYolov2Options } from '../tinyYolov2'; +export class TinyFaceDetectorOptions extends TinyYolov2Options { + constructor() { + super(...arguments); + this._name = 'TinyFaceDetectorOptions'; + } +} +//# sourceMappingURL=TinyFaceDetectorOptions.js.map \ No newline at end of file diff --git a/build/tinyFaceDetector/TinyFaceDetectorOptions.js.map b/build/tinyFaceDetector/TinyFaceDetectorOptions.js.map new file mode 100644 index 0000000..a468927 --- /dev/null +++ b/build/tinyFaceDetector/TinyFaceDetectorOptions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"TinyFaceDetectorOptions.js","sourceRoot":"","sources":["../../src/tinyFaceDetector/TinyFaceDetectorOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAItE,MAAM,OAAO,uBAAwB,SAAQ,iBAAiB;IAA9D;;QACY,UAAK,GAAW,yBAAyB,CAAA;IACrD,CAAC;CAAA"} \ No newline at end of file diff --git a/build/tinyFaceDetector/const.d.ts b/build/tinyFaceDetector/const.d.ts new file mode 100644 index 0000000..2efa870 --- /dev/null +++ b/build/tinyFaceDetector/const.d.ts @@ -0,0 +1,4 @@ +import { Point } from '../classes'; +export declare const IOU_THRESHOLD = 0.4; +export declare const BOX_ANCHORS: Point[]; +export declare const MEAN_RGB: [number, number, number]; diff --git a/build/tinyFaceDetector/const.js b/build/tinyFaceDetector/const.js new file mode 100644 index 0000000..f1cbe87 --- /dev/null +++ b/build/tinyFaceDetector/const.js @@ -0,0 +1,11 @@ +import { Point } from '../classes'; +export const IOU_THRESHOLD = 0.4; +export const BOX_ANCHORS = [ + new Point(1.603231, 2.094468), + new Point(6.041143, 7.080126), + new Point(2.882459, 3.518061), + new Point(4.266906, 5.178857), + new Point(9.041765, 10.66308) +]; +export const MEAN_RGB = [117.001, 114.697, 97.404]; +//# sourceMappingURL=const.js.map \ No newline at end of file diff --git a/build/tinyFaceDetector/const.js.map b/build/tinyFaceDetector/const.js.map new file mode 100644 index 0000000..041f497 --- /dev/null +++ b/build/tinyFaceDetector/const.js.map @@ -0,0 +1 @@ +{"version":3,"file":"const.js","sourceRoot":"","sources":["../../src/tinyFaceDetector/const.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElC,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAA;AAEhC,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC9B,CAAA;AAED,MAAM,CAAC,MAAM,QAAQ,GAA6B,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA"} \ No newline at end of file diff --git a/build/tinyFaceDetector/index.d.ts b/build/tinyFaceDetector/index.d.ts new file mode 100644 index 0000000..cde93ca --- /dev/null +++ b/build/tinyFaceDetector/index.d.ts @@ -0,0 +1,4 @@ +import { TinyFaceDetector } from './TinyFaceDetector'; +export * from './TinyFaceDetector'; +export * from './TinyFaceDetectorOptions'; +export declare function createTinyFaceDetector(weights: Float32Array): TinyFaceDetector; diff --git a/build/tinyFaceDetector/index.js b/build/tinyFaceDetector/index.js new file mode 100644 index 0000000..0c0bd91 --- /dev/null +++ b/build/tinyFaceDetector/index.js @@ -0,0 +1,9 @@ +import { TinyFaceDetector } from './TinyFaceDetector'; +export * from './TinyFaceDetector'; +export * from './TinyFaceDetectorOptions'; +export function createTinyFaceDetector(weights) { + const net = new TinyFaceDetector(); + net.extractWeights(weights); + return net; +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/tinyFaceDetector/index.js.map b/build/tinyFaceDetector/index.js.map new file mode 100644 index 0000000..fb02caa --- /dev/null +++ b/build/tinyFaceDetector/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tinyFaceDetector/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAE1C,MAAM,UAAU,sBAAsB,CAAC,OAAqB;IAC1D,MAAM,GAAG,GAAG,IAAI,gBAAgB,EAAE,CAAA;IAClC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IAC3B,OAAO,GAAG,CAAA;AACZ,CAAC"} \ No newline at end of file diff --git a/build/tinyYolov2/TinyYolov2.d.ts b/build/tinyYolov2/TinyYolov2.d.ts new file mode 100644 index 0000000..7ee0946 --- /dev/null +++ b/build/tinyYolov2/TinyYolov2.d.ts @@ -0,0 +1,18 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { FaceDetection, Point } from '../classes'; +import { ParamMapping } from '../common/types'; +import { TNetInput } from '../dom/types'; +import { TinyYolov2Base } from './TinyYolov2Base'; +import { ITinyYolov2Options } from './TinyYolov2Options'; +import { TinyYolov2NetParams } from './types'; +export declare class TinyYolov2 extends TinyYolov2Base { + constructor(withSeparableConvs?: boolean); + get withSeparableConvs(): boolean; + get anchors(): Point[]; + locateFaces(input: TNetInput, forwardParams: ITinyYolov2Options): Promise; + protected getDefaultModelName(): string; + protected extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap): { + params: TinyYolov2NetParams; + paramMappings: ParamMapping[]; + }; +} diff --git a/build/tinyYolov2/TinyYolov2.js b/build/tinyYolov2/TinyYolov2.js new file mode 100644 index 0000000..a69ea6d --- /dev/null +++ b/build/tinyYolov2/TinyYolov2.js @@ -0,0 +1,38 @@ +import { FaceDetection } from '../classes'; +import { BOX_ANCHORS, BOX_ANCHORS_SEPARABLE, DEFAULT_MODEL_NAME, DEFAULT_MODEL_NAME_SEPARABLE_CONV, IOU_THRESHOLD, MEAN_RGB_SEPARABLE, } from './const'; +import { TinyYolov2Base } from './TinyYolov2Base'; +export class TinyYolov2 extends TinyYolov2Base { + constructor(withSeparableConvs = true) { + const config = Object.assign({}, { + withSeparableConvs, + iouThreshold: IOU_THRESHOLD, + classes: ['face'] + }, withSeparableConvs + ? { + anchors: BOX_ANCHORS_SEPARABLE, + meanRgb: MEAN_RGB_SEPARABLE + } + : { + anchors: BOX_ANCHORS, + withClassScores: true + }); + super(config); + } + get withSeparableConvs() { + return this.config.withSeparableConvs; + } + get anchors() { + return this.config.anchors; + } + async locateFaces(input, forwardParams) { + const objectDetections = await this.detect(input, forwardParams); + return objectDetections.map(det => new FaceDetection(det.score, det.relativeBox, { width: det.imageWidth, height: det.imageHeight })); + } + getDefaultModelName() { + return this.withSeparableConvs ? DEFAULT_MODEL_NAME_SEPARABLE_CONV : DEFAULT_MODEL_NAME; + } + extractParamsFromWeigthMap(weightMap) { + return super.extractParamsFromWeigthMap(weightMap); + } +} +//# sourceMappingURL=TinyYolov2.js.map \ No newline at end of file diff --git a/build/tinyYolov2/TinyYolov2.js.map b/build/tinyYolov2/TinyYolov2.js.map new file mode 100644 index 0000000..56e0b40 --- /dev/null +++ b/build/tinyYolov2/TinyYolov2.js.map @@ -0,0 +1 @@ +{"version":3,"file":"TinyYolov2.js","sourceRoot":"","sources":["../../src/tinyYolov2/TinyYolov2.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAS,MAAM,YAAY,CAAC;AAGlD,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,iCAAiC,EACjC,aAAa,EACb,kBAAkB,GACnB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIlD,MAAM,OAAO,UAAW,SAAQ,cAAc;IAE5C,YAAY,qBAA8B,IAAI;QAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE;YAC/B,kBAAkB;YAClB,YAAY,EAAE,aAAa;YAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;SAClB,EACD,kBAAkB;YAChB,CAAC,CAAC;gBACA,OAAO,EAAE,qBAAqB;gBAC9B,OAAO,EAAE,kBAAkB;aAC5B;YACD,CAAC,CAAC;gBACA,OAAO,EAAE,WAAW;gBACpB,eAAe,EAAE,IAAI;aACtB,CACF,CAAA;QAED,KAAK,CAAC,MAAM,CAAC,CAAA;IACf,CAAC;IAED,IAAW,kBAAkB;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAA;IACvC,CAAC;IAED,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,KAAgB,EAAE,aAAiC;QAC1E,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,CAAA;QAChE,OAAO,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;IACvI,CAAC;IAES,mBAAmB;QAC3B,OAAO,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,kBAAkB,CAAA;IACzF,CAAC;IAES,0BAA0B,CAAC,SAA4B;QAC/D,OAAO,KAAK,CAAC,0BAA0B,CAAC,SAAS,CAAC,CAAA;IACpD,CAAC;CACF"} \ No newline at end of file diff --git a/build/tinyYolov2/TinyYolov2Base.d.ts b/build/tinyYolov2/TinyYolov2Base.d.ts new file mode 100644 index 0000000..558e01f --- /dev/null +++ b/build/tinyYolov2/TinyYolov2Base.d.ts @@ -0,0 +1,42 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { BoundingBox } from '../classes/BoundingBox'; +import { Dimensions } from '../classes/Dimensions'; +import { ObjectDetection } from '../classes/ObjectDetection'; +import { NetInput } from '../dom/NetInput'; +import { TNetInput } from '../dom/types'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { TinyYolov2Config } from './config'; +import { ITinyYolov2Options } from './TinyYolov2Options'; +import { DefaultTinyYolov2NetParams, MobilenetParams, TinyYolov2NetParams } from './types'; +export declare class TinyYolov2Base extends NeuralNetwork { + static DEFAULT_FILTER_SIZES: number[]; + private _config; + constructor(config: TinyYolov2Config); + get config(): TinyYolov2Config; + get withClassScores(): boolean; + get boxEncodingSize(): number; + runTinyYolov2(x: tf.Tensor4D, params: DefaultTinyYolov2NetParams): tf.Tensor4D; + runMobilenet(x: tf.Tensor4D, params: MobilenetParams): tf.Tensor4D; + forwardInput(input: NetInput, inputSize: number): tf.Tensor4D; + forward(input: TNetInput, inputSize: number): Promise; + detect(input: TNetInput, forwardParams?: ITinyYolov2Options): Promise; + protected getDefaultModelName(): string; + protected extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap): { + params: TinyYolov2NetParams; + paramMappings: import("../common").ParamMapping[]; + }; + protected extractParams(weights: Float32Array): { + params: TinyYolov2NetParams; + paramMappings: import("../common").ParamMapping[]; + }; + protected extractBoxes(outputTensor: tf.Tensor4D, inputBlobDimensions: Dimensions, scoreThreshold?: number): Promise<{ + row: number; + col: number; + anchor: number; + box: BoundingBox; + score: number; + classScore: number; + label: number; + }[]>; + private extractPredictedClass; +} diff --git a/build/tinyYolov2/TinyYolov2Base.js b/build/tinyYolov2/TinyYolov2Base.js new file mode 100644 index 0000000..051ee3f --- /dev/null +++ b/build/tinyYolov2/TinyYolov2Base.js @@ -0,0 +1,186 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { BoundingBox } from '../classes/BoundingBox'; +import { ObjectDetection } from '../classes/ObjectDetection'; +import { convLayer } from '../common'; +import { toNetInput } from '../dom'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { sigmoid } from '../ops'; +import { nonMaxSuppression } from '../ops/nonMaxSuppression'; +import { normalize } from '../ops/normalize'; +import { validateConfig } from './config'; +import { convWithBatchNorm } from './convWithBatchNorm'; +import { depthwiseSeparableConv } from './depthwiseSeparableConv'; +import { extractParams } from './extractParams'; +import { extractParamsFromWeigthMap } from './extractParamsFromWeigthMap'; +import { leaky } from './leaky'; +import { TinyYolov2Options } from './TinyYolov2Options'; +export class TinyYolov2Base extends NeuralNetwork { + constructor(config) { + super('TinyYolov2'); + validateConfig(config); + this._config = config; + } + get config() { + return this._config; + } + get withClassScores() { + return this.config.withClassScores || this.config.classes.length > 1; + } + get boxEncodingSize() { + return 5 + (this.withClassScores ? this.config.classes.length : 0); + } + runTinyYolov2(x, params) { + let out = convWithBatchNorm(x, params.conv0); + out = tf.maxPool(out, [2, 2], [2, 2], 'same'); + out = convWithBatchNorm(out, params.conv1); + out = tf.maxPool(out, [2, 2], [2, 2], 'same'); + out = convWithBatchNorm(out, params.conv2); + out = tf.maxPool(out, [2, 2], [2, 2], 'same'); + out = convWithBatchNorm(out, params.conv3); + out = tf.maxPool(out, [2, 2], [2, 2], 'same'); + out = convWithBatchNorm(out, params.conv4); + out = tf.maxPool(out, [2, 2], [2, 2], 'same'); + out = convWithBatchNorm(out, params.conv5); + out = tf.maxPool(out, [2, 2], [1, 1], 'same'); + out = convWithBatchNorm(out, params.conv6); + out = convWithBatchNorm(out, params.conv7); + return convLayer(out, params.conv8, 'valid', false); + } + runMobilenet(x, params) { + let out = this.config.isFirstLayerConv2d + ? leaky(convLayer(x, params.conv0, 'valid', false)) + : depthwiseSeparableConv(x, params.conv0); + out = tf.maxPool(out, [2, 2], [2, 2], 'same'); + out = depthwiseSeparableConv(out, params.conv1); + out = tf.maxPool(out, [2, 2], [2, 2], 'same'); + out = depthwiseSeparableConv(out, params.conv2); + out = tf.maxPool(out, [2, 2], [2, 2], 'same'); + out = depthwiseSeparableConv(out, params.conv3); + out = tf.maxPool(out, [2, 2], [2, 2], 'same'); + out = depthwiseSeparableConv(out, params.conv4); + out = tf.maxPool(out, [2, 2], [2, 2], 'same'); + out = depthwiseSeparableConv(out, params.conv5); + out = tf.maxPool(out, [2, 2], [1, 1], 'same'); + out = params.conv6 ? depthwiseSeparableConv(out, params.conv6) : out; + out = params.conv7 ? depthwiseSeparableConv(out, params.conv7) : out; + return convLayer(out, params.conv8, 'valid', false); + } + forwardInput(input, inputSize) { + const { params } = this; + if (!params) { + throw new Error('TinyYolov2 - load model before inference'); + } + return tf.tidy(() => { + let batchTensor = input.toBatchTensor(inputSize, false).toFloat(); + batchTensor = this.config.meanRgb + ? normalize(batchTensor, this.config.meanRgb) + : batchTensor; + batchTensor = batchTensor.div(tf.scalar(256)); + return this.config.withSeparableConvs + ? this.runMobilenet(batchTensor, params) + : this.runTinyYolov2(batchTensor, params); + }); + } + async forward(input, inputSize) { + return await this.forwardInput(await toNetInput(input), inputSize); + } + async detect(input, forwardParams = {}) { + const { inputSize, scoreThreshold } = new TinyYolov2Options(forwardParams); + const netInput = await toNetInput(input); + const out = await this.forwardInput(netInput, inputSize); + const out0 = tf.tidy(() => tf.unstack(out)[0].expandDims()); + const inputDimensions = { + width: netInput.getInputWidth(0), + height: netInput.getInputHeight(0) + }; + const results = await this.extractBoxes(out0, netInput.getReshapedInputDimensions(0), scoreThreshold); + out.dispose(); + out0.dispose(); + const boxes = results.map(res => res.box); + const scores = results.map(res => res.score); + const classScores = results.map(res => res.classScore); + const classNames = results.map(res => this.config.classes[res.label]); + const indices = nonMaxSuppression(boxes.map(box => box.rescale(inputSize)), scores, this.config.iouThreshold, true); + const detections = indices.map(idx => new ObjectDetection(scores[idx], classScores[idx], classNames[idx], boxes[idx], inputDimensions)); + return detections; + } + getDefaultModelName() { + return ''; + } + extractParamsFromWeigthMap(weightMap) { + return extractParamsFromWeigthMap(weightMap, this.config); + } + extractParams(weights) { + const filterSizes = this.config.filterSizes || TinyYolov2Base.DEFAULT_FILTER_SIZES; + const numFilters = filterSizes ? filterSizes.length : undefined; + if (numFilters !== 7 && numFilters !== 8 && numFilters !== 9) { + throw new Error(`TinyYolov2 - expected 7 | 8 | 9 convolutional filters, but found ${numFilters} filterSizes in config`); + } + return extractParams(weights, this.config, this.boxEncodingSize, filterSizes); + } + async extractBoxes(outputTensor, inputBlobDimensions, scoreThreshold) { + const { width, height } = inputBlobDimensions; + const inputSize = Math.max(width, height); + const correctionFactorX = inputSize / width; + const correctionFactorY = inputSize / height; + const numCells = outputTensor.shape[1]; + const numBoxes = this.config.anchors.length; + const [boxesTensor, scoresTensor, classScoresTensor] = tf.tidy(() => { + const reshaped = outputTensor.reshape([numCells, numCells, numBoxes, this.boxEncodingSize]); + const boxes = reshaped.slice([0, 0, 0, 0], [numCells, numCells, numBoxes, 4]); + const scores = reshaped.slice([0, 0, 0, 4], [numCells, numCells, numBoxes, 1]); + const classScores = this.withClassScores + ? tf.softmax(reshaped.slice([0, 0, 0, 5], [numCells, numCells, numBoxes, this.config.classes.length]), 3) + : tf.scalar(0); + return [boxes, scores, classScores]; + }); + const results = []; + const scoresData = await scoresTensor.array(); + const boxesData = await boxesTensor.array(); + for (let row = 0; row < numCells; row++) { + for (let col = 0; col < numCells; col++) { + for (let anchor = 0; anchor < numBoxes; anchor++) { + const score = sigmoid(scoresData[row][col][anchor][0]); + if (!scoreThreshold || score > scoreThreshold) { + const ctX = ((col + sigmoid(boxesData[row][col][anchor][0])) / numCells) * correctionFactorX; + const ctY = ((row + sigmoid(boxesData[row][col][anchor][1])) / numCells) * correctionFactorY; + const width = ((Math.exp(boxesData[row][col][anchor][2]) * this.config.anchors[anchor].x) / numCells) * correctionFactorX; + const height = ((Math.exp(boxesData[row][col][anchor][3]) * this.config.anchors[anchor].y) / numCells) * correctionFactorY; + const x = (ctX - (width / 2)); + const y = (ctY - (height / 2)); + const pos = { row, col, anchor }; + const { classScore, label } = this.withClassScores + ? await this.extractPredictedClass(classScoresTensor, pos) + : { classScore: 1, label: 0 }; + results.push({ + box: new BoundingBox(x, y, x + width, y + height), + score: score, + classScore: score * classScore, + label, + ...pos + }); + } + } + } + } + boxesTensor.dispose(); + scoresTensor.dispose(); + classScoresTensor.dispose(); + return results; + } + async extractPredictedClass(classesTensor, pos) { + const { row, col, anchor } = pos; + const classesData = await classesTensor.array(); + return Array(this.config.classes.length).fill(0) + .map((_, i) => classesData[row][col][anchor][i]) + .map((classScore, label) => ({ + classScore, + label + })) + .reduce((max, curr) => max.classScore > curr.classScore ? max : curr); + } +} +TinyYolov2Base.DEFAULT_FILTER_SIZES = [ + 3, 16, 32, 64, 128, 256, 512, 1024, 1024 +]; +//# sourceMappingURL=TinyYolov2Base.js.map \ No newline at end of file diff --git a/build/tinyYolov2/TinyYolov2Base.js.map b/build/tinyYolov2/TinyYolov2Base.js.map new file mode 100644 index 0000000..e507cbd --- /dev/null +++ b/build/tinyYolov2/TinyYolov2Base.js.map @@ -0,0 +1 @@ +{"version":3,"file":"TinyYolov2Base.js","sourceRoot":"","sources":["../../src/tinyYolov2/TinyYolov2Base.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/tinyYolov2/TinyYolov2Options.d.ts b/build/tinyYolov2/TinyYolov2Options.d.ts new file mode 100644 index 0000000..ee5c17f --- /dev/null +++ b/build/tinyYolov2/TinyYolov2Options.d.ts @@ -0,0 +1,18 @@ +export declare enum TinyYolov2SizeType { + XS = 224, + SM = 320, + MD = 416, + LG = 608 +} +export interface ITinyYolov2Options { + inputSize?: number; + scoreThreshold?: number; +} +export declare class TinyYolov2Options { + protected _name: string; + private _inputSize; + private _scoreThreshold; + constructor({ inputSize, scoreThreshold }?: ITinyYolov2Options); + get inputSize(): number; + get scoreThreshold(): number; +} diff --git a/build/tinyYolov2/TinyYolov2Options.js b/build/tinyYolov2/TinyYolov2Options.js new file mode 100644 index 0000000..679a167 --- /dev/null +++ b/build/tinyYolov2/TinyYolov2Options.js @@ -0,0 +1,23 @@ +export var TinyYolov2SizeType; +(function (TinyYolov2SizeType) { + TinyYolov2SizeType[TinyYolov2SizeType["XS"] = 224] = "XS"; + TinyYolov2SizeType[TinyYolov2SizeType["SM"] = 320] = "SM"; + TinyYolov2SizeType[TinyYolov2SizeType["MD"] = 416] = "MD"; + TinyYolov2SizeType[TinyYolov2SizeType["LG"] = 608] = "LG"; +})(TinyYolov2SizeType || (TinyYolov2SizeType = {})); +export class TinyYolov2Options { + constructor({ inputSize, scoreThreshold } = {}) { + this._name = 'TinyYolov2Options'; + this._inputSize = inputSize || 416; + this._scoreThreshold = scoreThreshold || 0.5; + if (typeof this._inputSize !== 'number' || this._inputSize % 32 !== 0) { + throw new Error(`${this._name} - expected inputSize to be a number divisible by 32`); + } + if (typeof this._scoreThreshold !== 'number' || this._scoreThreshold <= 0 || this._scoreThreshold >= 1) { + throw new Error(`${this._name} - expected scoreThreshold to be a number between 0 and 1`); + } + } + get inputSize() { return this._inputSize; } + get scoreThreshold() { return this._scoreThreshold; } +} +//# sourceMappingURL=TinyYolov2Options.js.map \ No newline at end of file diff --git a/build/tinyYolov2/TinyYolov2Options.js.map b/build/tinyYolov2/TinyYolov2Options.js.map new file mode 100644 index 0000000..b5cdada --- /dev/null +++ b/build/tinyYolov2/TinyYolov2Options.js.map @@ -0,0 +1 @@ +{"version":3,"file":"TinyYolov2Options.js","sourceRoot":"","sources":["../../src/tinyYolov2/TinyYolov2Options.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,kBAKX;AALD,WAAY,kBAAkB;IAC5B,yDAAQ,CAAA;IACR,yDAAQ,CAAA;IACR,yDAAQ,CAAA;IACR,yDAAQ,CAAA;AACV,CAAC,EALW,kBAAkB,KAAlB,kBAAkB,QAK7B;AAOD,MAAM,OAAO,iBAAiB;IAM5B,YAAY,EAAE,SAAS,EAAE,cAAc,KAAyB,EAAE;QALxD,UAAK,GAAW,mBAAmB,CAAA;QAM3C,IAAI,CAAC,UAAU,GAAG,SAAS,IAAI,GAAG,CAAA;QAClC,IAAI,CAAC,eAAe,GAAG,cAAc,IAAI,GAAG,CAAA;QAE5C,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,GAAG,EAAE,KAAK,CAAC,EAAE;YACrE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,sDAAsD,CAAC,CAAA;SACrF;QAED,IAAI,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,IAAI,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,IAAI,CAAC,eAAe,IAAI,CAAC,EAAE;YACtG,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,2DAA2D,CAAC,CAAA;SAC1F;IACH,CAAC;IAED,IAAI,SAAS,KAAa,OAAO,IAAI,CAAC,UAAU,CAAA,CAAC,CAAC;IAClD,IAAI,cAAc,KAAa,OAAO,IAAI,CAAC,eAAe,CAAA,CAAC,CAAC;CAC7D"} \ No newline at end of file diff --git a/build/tinyYolov2/config.d.ts b/build/tinyYolov2/config.d.ts new file mode 100644 index 0000000..4158ad0 --- /dev/null +++ b/build/tinyYolov2/config.d.ts @@ -0,0 +1,12 @@ +import { Point } from '../classes/Point'; +export declare type TinyYolov2Config = { + withSeparableConvs: boolean; + iouThreshold: number; + anchors: Point[]; + classes: string[]; + meanRgb?: [number, number, number]; + withClassScores?: boolean; + filterSizes?: number[]; + isFirstLayerConv2d?: boolean; +}; +export declare function validateConfig(config: any): void; diff --git a/build/tinyYolov2/config.js b/build/tinyYolov2/config.js new file mode 100644 index 0000000..d492168 --- /dev/null +++ b/build/tinyYolov2/config.js @@ -0,0 +1,28 @@ +const isNumber = (arg) => typeof arg === 'number'; +export function validateConfig(config) { + if (!config) { + throw new Error(`invalid config: ${config}`); + } + if (typeof config.withSeparableConvs !== 'boolean') { + throw new Error(`config.withSeparableConvs has to be a boolean, have: ${config.withSeparableConvs}`); + } + if (!isNumber(config.iouThreshold) || config.iouThreshold < 0 || config.iouThreshold > 1.0) { + throw new Error(`config.iouThreshold has to be a number between [0, 1], have: ${config.iouThreshold}`); + } + if (!Array.isArray(config.classes) + || !config.classes.length + || !config.classes.every((c) => typeof c === 'string')) { + throw new Error(`config.classes has to be an array class names: string[], have: ${JSON.stringify(config.classes)}`); + } + if (!Array.isArray(config.anchors) + || !config.anchors.length + || !config.anchors.map((a) => a || {}).every((a) => isNumber(a.x) && isNumber(a.y))) { + throw new Error(`config.anchors has to be an array of { x: number, y: number }, have: ${JSON.stringify(config.anchors)}`); + } + if (config.meanRgb && (!Array.isArray(config.meanRgb) + || config.meanRgb.length !== 3 + || !config.meanRgb.every(isNumber))) { + throw new Error(`config.meanRgb has to be an array of shape [number, number, number], have: ${JSON.stringify(config.meanRgb)}`); + } +} +//# sourceMappingURL=config.js.map \ No newline at end of file diff --git a/build/tinyYolov2/config.js.map b/build/tinyYolov2/config.js.map new file mode 100644 index 0000000..cfc4b02 --- /dev/null +++ b/build/tinyYolov2/config.js.map @@ -0,0 +1 @@ +{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/tinyYolov2/config.ts"],"names":[],"mappings":"AAaA,MAAM,QAAQ,GAAG,CAAC,GAAQ,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAA;AAEtD,MAAM,UAAU,cAAc,CAAC,MAAW;IACxC,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAA;KAC7C;IAED,IAAI,OAAO,MAAM,CAAC,kBAAkB,KAAK,SAAS,EAAE;QAClD,MAAM,IAAI,KAAK,CAAC,wDAAwD,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAA;KACrG;IAED,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,YAAY,GAAG,CAAC,IAAI,MAAM,CAAC,YAAY,GAAG,GAAG,EAAE;QAC1F,MAAM,IAAI,KAAK,CAAC,gEAAgE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAA;KACvG;IAED,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;WAC3B,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM;WACtB,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAC3D;QAEA,MAAM,IAAI,KAAK,CAAC,kEAAkE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;KACpH;IAED,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;WAC3B,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM;WACtB,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAC7F;QAEA,MAAM,IAAI,KAAK,CAAC,wEAAwE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;KAC1H;IAED,IAAI,MAAM,CAAC,OAAO,IAAI,CACpB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;WAC3B,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;WAC3B,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CACnC,EAAE;QAED,MAAM,IAAI,KAAK,CAAC,8EAA8E,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;KAChI;AACH,CAAC"} \ No newline at end of file diff --git a/build/tinyYolov2/const.d.ts b/build/tinyYolov2/const.d.ts new file mode 100644 index 0000000..9f3fd32 --- /dev/null +++ b/build/tinyYolov2/const.d.ts @@ -0,0 +1,7 @@ +import { Point } from '../classes'; +export declare const IOU_THRESHOLD = 0.4; +export declare const BOX_ANCHORS: Point[]; +export declare const BOX_ANCHORS_SEPARABLE: Point[]; +export declare const MEAN_RGB_SEPARABLE: [number, number, number]; +export declare const DEFAULT_MODEL_NAME = "tiny_yolov2_model"; +export declare const DEFAULT_MODEL_NAME_SEPARABLE_CONV = "tiny_yolov2_separable_conv_model"; diff --git a/build/tinyYolov2/const.js b/build/tinyYolov2/const.js new file mode 100644 index 0000000..75ac107 --- /dev/null +++ b/build/tinyYolov2/const.js @@ -0,0 +1,20 @@ +import { Point } from '../classes'; +export const IOU_THRESHOLD = 0.4; +export const BOX_ANCHORS = [ + new Point(0.738768, 0.874946), + new Point(2.42204, 2.65704), + new Point(4.30971, 7.04493), + new Point(10.246, 4.59428), + new Point(12.6868, 11.8741) +]; +export const BOX_ANCHORS_SEPARABLE = [ + new Point(1.603231, 2.094468), + new Point(6.041143, 7.080126), + new Point(2.882459, 3.518061), + new Point(4.266906, 5.178857), + new Point(9.041765, 10.66308) +]; +export const MEAN_RGB_SEPARABLE = [117.001, 114.697, 97.404]; +export const DEFAULT_MODEL_NAME = 'tiny_yolov2_model'; +export const DEFAULT_MODEL_NAME_SEPARABLE_CONV = 'tiny_yolov2_separable_conv_model'; +//# sourceMappingURL=const.js.map \ No newline at end of file diff --git a/build/tinyYolov2/const.js.map b/build/tinyYolov2/const.js.map new file mode 100644 index 0000000..05b52d2 --- /dev/null +++ b/build/tinyYolov2/const.js.map @@ -0,0 +1 @@ +{"version":3,"file":"const.js","sourceRoot":"","sources":["../../src/tinyYolov2/const.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAA;AAEhC,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,IAAI,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC;IAC3B,IAAI,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC;IAC3B,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1B,IAAI,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC;CAC5B,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC9B,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAA6B,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;AAEtF,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAAA;AACrD,MAAM,CAAC,MAAM,iCAAiC,GAAG,kCAAkC,CAAA"} \ No newline at end of file diff --git a/build/tinyYolov2/convWithBatchNorm.d.ts b/build/tinyYolov2/convWithBatchNorm.d.ts new file mode 100644 index 0000000..f6ecdb9 --- /dev/null +++ b/build/tinyYolov2/convWithBatchNorm.d.ts @@ -0,0 +1,3 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { ConvWithBatchNorm } from './types'; +export declare function convWithBatchNorm(x: tf.Tensor4D, params: ConvWithBatchNorm): tf.Tensor4D; diff --git a/build/tinyYolov2/convWithBatchNorm.js b/build/tinyYolov2/convWithBatchNorm.js new file mode 100644 index 0000000..3f8e503 --- /dev/null +++ b/build/tinyYolov2/convWithBatchNorm.js @@ -0,0 +1,13 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { leaky } from './leaky'; +export function convWithBatchNorm(x, params) { + return tf.tidy(() => { + let out = tf.pad(x, [[0, 0], [1, 1], [1, 1], [0, 0]]); + out = tf.conv2d(out, params.conv.filters, [1, 1], 'valid'); + out = tf.sub(out, params.bn.sub); + out = tf.mul(out, params.bn.truediv); + out = tf.add(out, params.conv.bias); + return leaky(out); + }); +} +//# sourceMappingURL=convWithBatchNorm.js.map \ No newline at end of file diff --git a/build/tinyYolov2/convWithBatchNorm.js.map b/build/tinyYolov2/convWithBatchNorm.js.map new file mode 100644 index 0000000..e858d16 --- /dev/null +++ b/build/tinyYolov2/convWithBatchNorm.js.map @@ -0,0 +1 @@ +{"version":3,"file":"convWithBatchNorm.js","sourceRoot":"","sources":["../../src/tinyYolov2/convWithBatchNorm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,MAAM,UAAU,iBAAiB,CAAC,CAAc,EAAE,MAAyB;IACzE,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QAClB,IAAI,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAgB,CAAA;QAEpE,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;QAC1D,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;QAChC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAA;QACpC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEnC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAA;IACnB,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/tinyYolov2/depthwiseSeparableConv.d.ts b/build/tinyYolov2/depthwiseSeparableConv.d.ts new file mode 100644 index 0000000..4274242 --- /dev/null +++ b/build/tinyYolov2/depthwiseSeparableConv.d.ts @@ -0,0 +1,3 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { SeparableConvParams } from '../common/types'; +export declare function depthwiseSeparableConv(x: tf.Tensor4D, params: SeparableConvParams): tf.Tensor4D; diff --git a/build/tinyYolov2/depthwiseSeparableConv.js b/build/tinyYolov2/depthwiseSeparableConv.js new file mode 100644 index 0000000..a8e8fd4 --- /dev/null +++ b/build/tinyYolov2/depthwiseSeparableConv.js @@ -0,0 +1,11 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { leaky } from './leaky'; +export function depthwiseSeparableConv(x, params) { + return tf.tidy(() => { + let out = tf.pad(x, [[0, 0], [1, 1], [1, 1], [0, 0]]); + out = tf.separableConv2d(out, params.depthwise_filter, params.pointwise_filter, [1, 1], 'valid'); + out = tf.add(out, params.bias); + return leaky(out); + }); +} +//# sourceMappingURL=depthwiseSeparableConv.js.map \ No newline at end of file diff --git a/build/tinyYolov2/depthwiseSeparableConv.js.map b/build/tinyYolov2/depthwiseSeparableConv.js.map new file mode 100644 index 0000000..e760b72 --- /dev/null +++ b/build/tinyYolov2/depthwiseSeparableConv.js.map @@ -0,0 +1 @@ +{"version":3,"file":"depthwiseSeparableConv.js","sourceRoot":"","sources":["../../src/tinyYolov2/depthwiseSeparableConv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAG5C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,MAAM,UAAU,sBAAsB,CAAC,CAAc,EAAE,MAA2B;IAChF,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QAClB,IAAI,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAgB,CAAA;QAEpE,GAAG,GAAG,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;QAChG,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QAE9B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAA;IACnB,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/tinyYolov2/extractParams.d.ts b/build/tinyYolov2/extractParams.d.ts new file mode 100644 index 0000000..2722193 --- /dev/null +++ b/build/tinyYolov2/extractParams.d.ts @@ -0,0 +1,7 @@ +import { ParamMapping } from '../common/types'; +import { TinyYolov2Config } from './config'; +import { TinyYolov2NetParams } from './types'; +export declare function extractParams(weights: Float32Array, config: TinyYolov2Config, boxEncodingSize: number, filterSizes: number[]): { + params: TinyYolov2NetParams; + paramMappings: ParamMapping[]; +}; diff --git a/build/tinyYolov2/extractParams.js b/build/tinyYolov2/extractParams.js new file mode 100644 index 0000000..e56fcbd --- /dev/null +++ b/build/tinyYolov2/extractParams.js @@ -0,0 +1,63 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { extractConvParamsFactory } from '../common'; +import { extractSeparableConvParamsFactory } from '../common/extractSeparableConvParamsFactory'; +import { extractWeightsFactory } from '../common/extractWeightsFactory'; +function extractorsFactory(extractWeights, paramMappings) { + const extractConvParams = extractConvParamsFactory(extractWeights, paramMappings); + function extractBatchNormParams(size, mappedPrefix) { + const sub = tf.tensor1d(extractWeights(size)); + const truediv = tf.tensor1d(extractWeights(size)); + paramMappings.push({ paramPath: `${mappedPrefix}/sub` }, { paramPath: `${mappedPrefix}/truediv` }); + return { sub, truediv }; + } + function extractConvWithBatchNormParams(channelsIn, channelsOut, mappedPrefix) { + const conv = extractConvParams(channelsIn, channelsOut, 3, `${mappedPrefix}/conv`); + const bn = extractBatchNormParams(channelsOut, `${mappedPrefix}/bn`); + return { conv, bn }; + } + const extractSeparableConvParams = extractSeparableConvParamsFactory(extractWeights, paramMappings); + return { + extractConvParams, + extractConvWithBatchNormParams, + extractSeparableConvParams + }; +} +export function extractParams(weights, config, boxEncodingSize, filterSizes) { + const { extractWeights, getRemainingWeights } = extractWeightsFactory(weights); + const paramMappings = []; + const { extractConvParams, extractConvWithBatchNormParams, extractSeparableConvParams } = extractorsFactory(extractWeights, paramMappings); + let params; + if (config.withSeparableConvs) { + const [s0, s1, s2, s3, s4, s5, s6, s7, s8] = filterSizes; + const conv0 = config.isFirstLayerConv2d + ? extractConvParams(s0, s1, 3, 'conv0') + : extractSeparableConvParams(s0, s1, 'conv0'); + const conv1 = extractSeparableConvParams(s1, s2, 'conv1'); + const conv2 = extractSeparableConvParams(s2, s3, 'conv2'); + const conv3 = extractSeparableConvParams(s3, s4, 'conv3'); + const conv4 = extractSeparableConvParams(s4, s5, 'conv4'); + const conv5 = extractSeparableConvParams(s5, s6, 'conv5'); + const conv6 = s7 ? extractSeparableConvParams(s6, s7, 'conv6') : undefined; + const conv7 = s8 ? extractSeparableConvParams(s7, s8, 'conv7') : undefined; + const conv8 = extractConvParams(s8 || s7 || s6, 5 * boxEncodingSize, 1, 'conv8'); + params = { conv0, conv1, conv2, conv3, conv4, conv5, conv6, conv7, conv8 }; + } + else { + const [s0, s1, s2, s3, s4, s5, s6, s7, s8] = filterSizes; + const conv0 = extractConvWithBatchNormParams(s0, s1, 'conv0'); + const conv1 = extractConvWithBatchNormParams(s1, s2, 'conv1'); + const conv2 = extractConvWithBatchNormParams(s2, s3, 'conv2'); + const conv3 = extractConvWithBatchNormParams(s3, s4, 'conv3'); + const conv4 = extractConvWithBatchNormParams(s4, s5, 'conv4'); + const conv5 = extractConvWithBatchNormParams(s5, s6, 'conv5'); + const conv6 = extractConvWithBatchNormParams(s6, s7, 'conv6'); + const conv7 = extractConvWithBatchNormParams(s7, s8, 'conv7'); + const conv8 = extractConvParams(s8, 5 * boxEncodingSize, 1, 'conv8'); + params = { conv0, conv1, conv2, conv3, conv4, conv5, conv6, conv7, conv8 }; + } + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { params, paramMappings }; +} +//# sourceMappingURL=extractParams.js.map \ No newline at end of file diff --git a/build/tinyYolov2/extractParams.js.map b/build/tinyYolov2/extractParams.js.map new file mode 100644 index 0000000..e0080c5 --- /dev/null +++ b/build/tinyYolov2/extractParams.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParams.js","sourceRoot":"","sources":["../../src/tinyYolov2/extractParams.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/tinyYolov2/extractParamsFromWeigthMap.d.ts b/build/tinyYolov2/extractParamsFromWeigthMap.d.ts new file mode 100644 index 0000000..a421696 --- /dev/null +++ b/build/tinyYolov2/extractParamsFromWeigthMap.d.ts @@ -0,0 +1,8 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { ParamMapping } from '../common/types'; +import { TinyYolov2Config } from './config'; +import { TinyYolov2NetParams } from './types'; +export declare function extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap, config: TinyYolov2Config): { + params: TinyYolov2NetParams; + paramMappings: ParamMapping[]; +}; diff --git a/build/tinyYolov2/extractParamsFromWeigthMap.js b/build/tinyYolov2/extractParamsFromWeigthMap.js new file mode 100644 index 0000000..30e2194 --- /dev/null +++ b/build/tinyYolov2/extractParamsFromWeigthMap.js @@ -0,0 +1,62 @@ +import { disposeUnusedWeightTensors } from '../common/disposeUnusedWeightTensors'; +import { loadSeparableConvParamsFactory } from '../common/extractSeparableConvParamsFactory'; +import { extractWeightEntryFactory } from '../common/extractWeightEntryFactory'; +function extractorsFactory(weightMap, paramMappings) { + const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); + function extractBatchNormParams(prefix) { + const sub = extractWeightEntry(`${prefix}/sub`, 1); + const truediv = extractWeightEntry(`${prefix}/truediv`, 1); + return { sub, truediv }; + } + function extractConvParams(prefix) { + const filters = extractWeightEntry(`${prefix}/filters`, 4); + const bias = extractWeightEntry(`${prefix}/bias`, 1); + return { filters, bias }; + } + function extractConvWithBatchNormParams(prefix) { + const conv = extractConvParams(`${prefix}/conv`); + const bn = extractBatchNormParams(`${prefix}/bn`); + return { conv, bn }; + } + const extractSeparableConvParams = loadSeparableConvParamsFactory(extractWeightEntry); + return { + extractConvParams, + extractConvWithBatchNormParams, + extractSeparableConvParams + }; +} +export function extractParamsFromWeigthMap(weightMap, config) { + const paramMappings = []; + const { extractConvParams, extractConvWithBatchNormParams, extractSeparableConvParams } = extractorsFactory(weightMap, paramMappings); + let params; + if (config.withSeparableConvs) { + const numFilters = (config.filterSizes && config.filterSizes.length || 9); + params = { + conv0: config.isFirstLayerConv2d ? extractConvParams('conv0') : extractSeparableConvParams('conv0'), + conv1: extractSeparableConvParams('conv1'), + conv2: extractSeparableConvParams('conv2'), + conv3: extractSeparableConvParams('conv3'), + conv4: extractSeparableConvParams('conv4'), + conv5: extractSeparableConvParams('conv5'), + conv6: numFilters > 7 ? extractSeparableConvParams('conv6') : undefined, + conv7: numFilters > 8 ? extractSeparableConvParams('conv7') : undefined, + conv8: extractConvParams('conv8') + }; + } + else { + params = { + conv0: extractConvWithBatchNormParams('conv0'), + conv1: extractConvWithBatchNormParams('conv1'), + conv2: extractConvWithBatchNormParams('conv2'), + conv3: extractConvWithBatchNormParams('conv3'), + conv4: extractConvWithBatchNormParams('conv4'), + conv5: extractConvWithBatchNormParams('conv5'), + conv6: extractConvWithBatchNormParams('conv6'), + conv7: extractConvWithBatchNormParams('conv7'), + conv8: extractConvParams('conv8') + }; + } + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} +//# sourceMappingURL=extractParamsFromWeigthMap.js.map \ No newline at end of file diff --git a/build/tinyYolov2/extractParamsFromWeigthMap.js.map b/build/tinyYolov2/extractParamsFromWeigthMap.js.map new file mode 100644 index 0000000..74f73fb --- /dev/null +++ b/build/tinyYolov2/extractParamsFromWeigthMap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParamsFromWeigthMap.js","sourceRoot":"","sources":["../../src/tinyYolov2/extractParamsFromWeigthMap.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/tinyYolov2/index.d.ts b/build/tinyYolov2/index.d.ts new file mode 100644 index 0000000..bfef96a --- /dev/null +++ b/build/tinyYolov2/index.d.ts @@ -0,0 +1,6 @@ +import { TinyYolov2 } from './TinyYolov2'; +export * from './TinyYolov2Options'; +export * from './config'; +export * from './types'; +export { TinyYolov2 }; +export declare function createTinyYolov2(weights: Float32Array, withSeparableConvs?: boolean): TinyYolov2; diff --git a/build/tinyYolov2/index.js b/build/tinyYolov2/index.js new file mode 100644 index 0000000..6714ce2 --- /dev/null +++ b/build/tinyYolov2/index.js @@ -0,0 +1,11 @@ +import { TinyYolov2 } from './TinyYolov2'; +export * from './TinyYolov2Options'; +export * from './config'; +export * from './types'; +export { TinyYolov2 }; +export function createTinyYolov2(weights, withSeparableConvs = true) { + const net = new TinyYolov2(withSeparableConvs); + net.extractWeights(weights); + return net; +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/tinyYolov2/index.js.map b/build/tinyYolov2/index.js.map new file mode 100644 index 0000000..ac186e5 --- /dev/null +++ b/build/tinyYolov2/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tinyYolov2/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,cAAc,qBAAqB,CAAC;AAEpC,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AAEvB,OAAO,EAAE,UAAU,EAAE,CAAA;AAErB,MAAM,UAAU,gBAAgB,CAAC,OAAqB,EAAE,qBAA8B,IAAI;IACxF,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAA;IAC9C,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IAC3B,OAAO,GAAG,CAAA;AACZ,CAAC"} \ No newline at end of file diff --git a/build/tinyYolov2/leaky.d.ts b/build/tinyYolov2/leaky.d.ts new file mode 100644 index 0000000..9bbf7f5 --- /dev/null +++ b/build/tinyYolov2/leaky.d.ts @@ -0,0 +1,2 @@ +import * as tf from '@tensorflow/tfjs-core'; +export declare function leaky(x: tf.Tensor4D): tf.Tensor4D; diff --git a/build/tinyYolov2/leaky.js b/build/tinyYolov2/leaky.js new file mode 100644 index 0000000..37b63f6 --- /dev/null +++ b/build/tinyYolov2/leaky.js @@ -0,0 +1,9 @@ +import * as tf from '@tensorflow/tfjs-core'; +export function leaky(x) { + return tf.tidy(() => { + const min = tf.mul(x, tf.scalar(0.10000000149011612)); + return tf.add(tf.relu(tf.sub(x, min)), min); + //return tf.maximum(x, min) + }); +} +//# sourceMappingURL=leaky.js.map \ No newline at end of file diff --git a/build/tinyYolov2/leaky.js.map b/build/tinyYolov2/leaky.js.map new file mode 100644 index 0000000..0ff8205 --- /dev/null +++ b/build/tinyYolov2/leaky.js.map @@ -0,0 +1 @@ +{"version":3,"file":"leaky.js","sourceRoot":"","sources":["../../src/tinyYolov2/leaky.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,MAAM,UAAU,KAAK,CAAC,CAAc;IAClC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QAClB,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAA;QACrD,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAC3C,2BAA2B;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/build/tinyYolov2/types.d.ts b/build/tinyYolov2/types.d.ts new file mode 100644 index 0000000..5c142f9 --- /dev/null +++ b/build/tinyYolov2/types.d.ts @@ -0,0 +1,34 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { ConvParams } from '../common'; +import { SeparableConvParams } from '../common/types'; +export declare type BatchNorm = { + sub: tf.Tensor1D; + truediv: tf.Tensor1D; +}; +export declare type ConvWithBatchNorm = { + conv: ConvParams; + bn: BatchNorm; +}; +export declare type MobilenetParams = { + conv0: SeparableConvParams | ConvParams; + conv1: SeparableConvParams; + conv2: SeparableConvParams; + conv3: SeparableConvParams; + conv4: SeparableConvParams; + conv5: SeparableConvParams; + conv6?: SeparableConvParams; + conv7?: SeparableConvParams; + conv8: ConvParams; +}; +export declare type DefaultTinyYolov2NetParams = { + conv0: ConvWithBatchNorm; + conv1: ConvWithBatchNorm; + conv2: ConvWithBatchNorm; + conv3: ConvWithBatchNorm; + conv4: ConvWithBatchNorm; + conv5: ConvWithBatchNorm; + conv6: ConvWithBatchNorm; + conv7: ConvWithBatchNorm; + conv8: ConvParams; +}; +export declare type TinyYolov2NetParams = DefaultTinyYolov2NetParams | MobilenetParams; diff --git a/build/tinyYolov2/types.js b/build/tinyYolov2/types.js new file mode 100644 index 0000000..5b2306a --- /dev/null +++ b/build/tinyYolov2/types.js @@ -0,0 +1 @@ +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/build/tinyYolov2/types.js.map b/build/tinyYolov2/types.js.map new file mode 100644 index 0000000..85a0149 --- /dev/null +++ b/build/tinyYolov2/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tinyYolov2/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/utils/index.d.ts b/build/utils/index.d.ts new file mode 100644 index 0000000..8fc6e76 --- /dev/null +++ b/build/utils/index.d.ts @@ -0,0 +1,17 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { Point } from '../classes'; +import { Dimensions, IDimensions } from '../classes/Dimensions'; +export declare function isTensor(tensor: any, dim: number): boolean; +export declare function isTensor1D(tensor: any): tensor is tf.Tensor1D; +export declare function isTensor2D(tensor: any): tensor is tf.Tensor2D; +export declare function isTensor3D(tensor: any): tensor is tf.Tensor3D; +export declare function isTensor4D(tensor: any): tensor is tf.Tensor4D; +export declare function isFloat(num: number): boolean; +export declare function isEven(num: number): boolean; +export declare function round(num: number, prec?: number): number; +export declare function isDimensions(obj: any): boolean; +export declare function computeReshapedDimensions({ width, height }: IDimensions, inputSize: number): Dimensions; +export declare function getCenterPoint(pts: Point[]): Point; +export declare function range(num: number, start: number, step: number): number[]; +export declare function isValidNumber(num: any): boolean; +export declare function isValidProbablitiy(num: any): boolean; diff --git a/build/utils/index.js b/build/utils/index.js new file mode 100644 index 0000000..f591532 --- /dev/null +++ b/build/utils/index.js @@ -0,0 +1,49 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { Point } from '../classes'; +import { Dimensions } from '../classes/Dimensions'; +export function isTensor(tensor, dim) { + return tensor instanceof tf.Tensor && tensor.shape.length === dim; +} +export function isTensor1D(tensor) { + return isTensor(tensor, 1); +} +export function isTensor2D(tensor) { + return isTensor(tensor, 2); +} +export function isTensor3D(tensor) { + return isTensor(tensor, 3); +} +export function isTensor4D(tensor) { + return isTensor(tensor, 4); +} +export function isFloat(num) { + return num % 1 !== 0; +} +export function isEven(num) { + return num % 2 === 0; +} +export function round(num, prec = 2) { + const f = Math.pow(10, prec); + return Math.floor(num * f) / f; +} +export function isDimensions(obj) { + return obj && obj.width && obj.height; +} +export function computeReshapedDimensions({ width, height }, inputSize) { + const scale = inputSize / Math.max(height, width); + return new Dimensions(Math.round(width * scale), Math.round(height * scale)); +} +export function getCenterPoint(pts) { + return pts.reduce((sum, pt) => sum.add(pt), new Point(0, 0)) + .div(new Point(pts.length, pts.length)); +} +export function range(num, start, step) { + return Array(num).fill(0).map((_, i) => start + (i * step)); +} +export function isValidNumber(num) { + return !!num && num !== Infinity && num !== -Infinity && !isNaN(num) || num === 0; +} +export function isValidProbablitiy(num) { + return isValidNumber(num) && 0 <= num && num <= 1.0; +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/utils/index.js.map b/build/utils/index.js.map new file mode 100644 index 0000000..6bc5339 --- /dev/null +++ b/build/utils/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/xception/TinyXception.d.ts b/build/xception/TinyXception.d.ts new file mode 100644 index 0000000..339dbcc --- /dev/null +++ b/build/xception/TinyXception.d.ts @@ -0,0 +1,19 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { NetInput, TNetInput } from '../dom'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { TinyXceptionParams } from './types'; +export declare class TinyXception extends NeuralNetwork { + private _numMainBlocks; + constructor(numMainBlocks: number); + forwardInput(input: NetInput): tf.Tensor4D; + forward(input: TNetInput): Promise; + protected getDefaultModelName(): string; + protected extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap): { + params: TinyXceptionParams; + paramMappings: import("../common").ParamMapping[]; + }; + protected extractParams(weights: Float32Array): { + params: TinyXceptionParams; + paramMappings: import("../common").ParamMapping[]; + }; +} diff --git a/build/xception/TinyXception.js b/build/xception/TinyXception.js new file mode 100644 index 0000000..d53a5ce --- /dev/null +++ b/build/xception/TinyXception.js @@ -0,0 +1,65 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { depthwiseSeparableConv } from '../common'; +import { toNetInput } from '../dom'; +import { NeuralNetwork } from '../NeuralNetwork'; +import { normalize } from '../ops'; +import { range } from '../utils'; +import { extractParams } from './extractParams'; +import { extractParamsFromWeigthMap } from './extractParamsFromWeigthMap'; +function conv(x, params, stride) { + return tf.add(tf.conv2d(x, params.filters, stride, 'same'), params.bias); +} +function reductionBlock(x, params, isActivateInput = true) { + let out = isActivateInput ? tf.relu(x) : x; + out = depthwiseSeparableConv(out, params.separable_conv0, [1, 1]); + out = depthwiseSeparableConv(tf.relu(out), params.separable_conv1, [1, 1]); + out = tf.maxPool(out, [3, 3], [2, 2], 'same'); + out = tf.add(out, conv(x, params.expansion_conv, [2, 2])); + return out; +} +function mainBlock(x, params) { + let out = depthwiseSeparableConv(tf.relu(x), params.separable_conv0, [1, 1]); + out = depthwiseSeparableConv(tf.relu(out), params.separable_conv1, [1, 1]); + out = depthwiseSeparableConv(tf.relu(out), params.separable_conv2, [1, 1]); + out = tf.add(out, x); + return out; +} +export class TinyXception extends NeuralNetwork { + constructor(numMainBlocks) { + super('TinyXception'); + this._numMainBlocks = numMainBlocks; + } + forwardInput(input) { + const { params } = this; + if (!params) { + throw new Error('TinyXception - load model before inference'); + } + return tf.tidy(() => { + const batchTensor = input.toBatchTensor(112, true); + const meanRgb = [122.782, 117.001, 104.298]; + const normalized = normalize(batchTensor, meanRgb).div(tf.scalar(256)); + let out = tf.relu(conv(normalized, params.entry_flow.conv_in, [2, 2])); + out = reductionBlock(out, params.entry_flow.reduction_block_0, false); + out = reductionBlock(out, params.entry_flow.reduction_block_1); + range(this._numMainBlocks, 0, 1).forEach((idx) => { + out = mainBlock(out, params.middle_flow[`main_block_${idx}`]); + }); + out = reductionBlock(out, params.exit_flow.reduction_block); + out = tf.relu(depthwiseSeparableConv(out, params.exit_flow.separable_conv, [1, 1])); + return out; + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + getDefaultModelName() { + return 'tiny_xception_model'; + } + extractParamsFromWeigthMap(weightMap) { + return extractParamsFromWeigthMap(weightMap, this._numMainBlocks); + } + extractParams(weights) { + return extractParams(weights, this._numMainBlocks); + } +} +//# sourceMappingURL=TinyXception.js.map \ No newline at end of file diff --git a/build/xception/TinyXception.js.map b/build/xception/TinyXception.js.map new file mode 100644 index 0000000..1ad4348 --- /dev/null +++ b/build/xception/TinyXception.js.map @@ -0,0 +1 @@ +{"version":3,"file":"TinyXception.js","sourceRoot":"","sources":["../../src/xception/TinyXception.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/xception/extractParams.d.ts b/build/xception/extractParams.d.ts new file mode 100644 index 0000000..886c5ca --- /dev/null +++ b/build/xception/extractParams.d.ts @@ -0,0 +1,6 @@ +import { ParamMapping } from '../common/types'; +import { TinyXceptionParams } from './types'; +export declare function extractParams(weights: Float32Array, numMainBlocks: number): { + params: TinyXceptionParams; + paramMappings: ParamMapping[]; +}; diff --git a/build/xception/extractParams.js b/build/xception/extractParams.js new file mode 100644 index 0000000..66772a5 --- /dev/null +++ b/build/xception/extractParams.js @@ -0,0 +1,55 @@ +import { extractConvParamsFactory, extractSeparableConvParamsFactory, extractWeightsFactory } from '../common'; +import { range } from '../utils'; +function extractorsFactory(extractWeights, paramMappings) { + const extractConvParams = extractConvParamsFactory(extractWeights, paramMappings); + const extractSeparableConvParams = extractSeparableConvParamsFactory(extractWeights, paramMappings); + function extractReductionBlockParams(channelsIn, channelsOut, mappedPrefix) { + const separable_conv0 = extractSeparableConvParams(channelsIn, channelsOut, `${mappedPrefix}/separable_conv0`); + const separable_conv1 = extractSeparableConvParams(channelsOut, channelsOut, `${mappedPrefix}/separable_conv1`); + const expansion_conv = extractConvParams(channelsIn, channelsOut, 1, `${mappedPrefix}/expansion_conv`); + return { separable_conv0, separable_conv1, expansion_conv }; + } + function extractMainBlockParams(channels, mappedPrefix) { + const separable_conv0 = extractSeparableConvParams(channels, channels, `${mappedPrefix}/separable_conv0`); + const separable_conv1 = extractSeparableConvParams(channels, channels, `${mappedPrefix}/separable_conv1`); + const separable_conv2 = extractSeparableConvParams(channels, channels, `${mappedPrefix}/separable_conv2`); + return { separable_conv0, separable_conv1, separable_conv2 }; + } + return { + extractConvParams, + extractSeparableConvParams, + extractReductionBlockParams, + extractMainBlockParams + }; +} +export function extractParams(weights, numMainBlocks) { + const paramMappings = []; + const { extractWeights, getRemainingWeights } = extractWeightsFactory(weights); + const { extractConvParams, extractSeparableConvParams, extractReductionBlockParams, extractMainBlockParams } = extractorsFactory(extractWeights, paramMappings); + const entry_flow_conv_in = extractConvParams(3, 32, 3, 'entry_flow/conv_in'); + const entry_flow_reduction_block_0 = extractReductionBlockParams(32, 64, 'entry_flow/reduction_block_0'); + const entry_flow_reduction_block_1 = extractReductionBlockParams(64, 128, 'entry_flow/reduction_block_1'); + const entry_flow = { + conv_in: entry_flow_conv_in, + reduction_block_0: entry_flow_reduction_block_0, + reduction_block_1: entry_flow_reduction_block_1 + }; + const middle_flow = {}; + range(numMainBlocks, 0, 1).forEach((idx) => { + middle_flow[`main_block_${idx}`] = extractMainBlockParams(128, `middle_flow/main_block_${idx}`); + }); + const exit_flow_reduction_block = extractReductionBlockParams(128, 256, 'exit_flow/reduction_block'); + const exit_flow_separable_conv = extractSeparableConvParams(256, 512, 'exit_flow/separable_conv'); + const exit_flow = { + reduction_block: exit_flow_reduction_block, + separable_conv: exit_flow_separable_conv + }; + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { + paramMappings, + params: { entry_flow, middle_flow, exit_flow } + }; +} +//# sourceMappingURL=extractParams.js.map \ No newline at end of file diff --git a/build/xception/extractParams.js.map b/build/xception/extractParams.js.map new file mode 100644 index 0000000..de87d79 --- /dev/null +++ b/build/xception/extractParams.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParams.js","sourceRoot":"","sources":["../../src/xception/extractParams.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/build/xception/extractParamsFromWeigthMap.d.ts b/build/xception/extractParamsFromWeigthMap.d.ts new file mode 100644 index 0000000..51e1911 --- /dev/null +++ b/build/xception/extractParamsFromWeigthMap.d.ts @@ -0,0 +1,7 @@ +import * as tf from '@tensorflow/tfjs-core'; +import { ParamMapping } from '../common'; +import { TinyXceptionParams } from './types'; +export declare function extractParamsFromWeigthMap(weightMap: tf.NamedTensorMap, numMainBlocks: number): { + params: TinyXceptionParams; + paramMappings: ParamMapping[]; +}; diff --git a/build/xception/extractParamsFromWeigthMap.js b/build/xception/extractParamsFromWeigthMap.js new file mode 100644 index 0000000..5bc6512 --- /dev/null +++ b/build/xception/extractParamsFromWeigthMap.js @@ -0,0 +1,51 @@ +import { disposeUnusedWeightTensors, extractWeightEntryFactory, loadSeparableConvParamsFactory, } from '../common'; +import { loadConvParamsFactory } from '../common/loadConvParamsFactory'; +import { range } from '../utils'; +function loadParamsFactory(weightMap, paramMappings) { + const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); + const extractConvParams = loadConvParamsFactory(extractWeightEntry); + const extractSeparableConvParams = loadSeparableConvParamsFactory(extractWeightEntry); + function extractReductionBlockParams(mappedPrefix) { + const separable_conv0 = extractSeparableConvParams(`${mappedPrefix}/separable_conv0`); + const separable_conv1 = extractSeparableConvParams(`${mappedPrefix}/separable_conv1`); + const expansion_conv = extractConvParams(`${mappedPrefix}/expansion_conv`); + return { separable_conv0, separable_conv1, expansion_conv }; + } + function extractMainBlockParams(mappedPrefix) { + const separable_conv0 = extractSeparableConvParams(`${mappedPrefix}/separable_conv0`); + const separable_conv1 = extractSeparableConvParams(`${mappedPrefix}/separable_conv1`); + const separable_conv2 = extractSeparableConvParams(`${mappedPrefix}/separable_conv2`); + return { separable_conv0, separable_conv1, separable_conv2 }; + } + return { + extractConvParams, + extractSeparableConvParams, + extractReductionBlockParams, + extractMainBlockParams + }; +} +export function extractParamsFromWeigthMap(weightMap, numMainBlocks) { + const paramMappings = []; + const { extractConvParams, extractSeparableConvParams, extractReductionBlockParams, extractMainBlockParams } = loadParamsFactory(weightMap, paramMappings); + const entry_flow_conv_in = extractConvParams('entry_flow/conv_in'); + const entry_flow_reduction_block_0 = extractReductionBlockParams('entry_flow/reduction_block_0'); + const entry_flow_reduction_block_1 = extractReductionBlockParams('entry_flow/reduction_block_1'); + const entry_flow = { + conv_in: entry_flow_conv_in, + reduction_block_0: entry_flow_reduction_block_0, + reduction_block_1: entry_flow_reduction_block_1 + }; + const middle_flow = {}; + range(numMainBlocks, 0, 1).forEach((idx) => { + middle_flow[`main_block_${idx}`] = extractMainBlockParams(`middle_flow/main_block_${idx}`); + }); + const exit_flow_reduction_block = extractReductionBlockParams('exit_flow/reduction_block'); + const exit_flow_separable_conv = extractSeparableConvParams('exit_flow/separable_conv'); + const exit_flow = { + reduction_block: exit_flow_reduction_block, + separable_conv: exit_flow_separable_conv + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params: { entry_flow, middle_flow, exit_flow }, paramMappings }; +} +//# sourceMappingURL=extractParamsFromWeigthMap.js.map \ No newline at end of file diff --git a/build/xception/extractParamsFromWeigthMap.js.map b/build/xception/extractParamsFromWeigthMap.js.map new file mode 100644 index 0000000..571f9c2 --- /dev/null +++ b/build/xception/extractParamsFromWeigthMap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extractParamsFromWeigthMap.js","sourceRoot":"","sources":["../../src/xception/extractParamsFromWeigthMap.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,8BAA8B,GAE/B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAGjC,SAAS,iBAAiB,CAAC,SAAc,EAAE,aAA6B;IAEtE,MAAM,kBAAkB,GAAG,yBAAyB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAE9E,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,kBAAkB,CAAC,CAAA;IACnE,MAAM,0BAA0B,GAAG,8BAA8B,CAAC,kBAAkB,CAAC,CAAA;IAErF,SAAS,2BAA2B,CAAC,YAAoB;QAEvD,MAAM,eAAe,GAAG,0BAA0B,CAAC,GAAG,YAAY,kBAAkB,CAAC,CAAA;QACrF,MAAM,eAAe,GAAG,0BAA0B,CAAC,GAAG,YAAY,kBAAkB,CAAC,CAAA;QACrF,MAAM,cAAc,GAAG,iBAAiB,CAAC,GAAG,YAAY,iBAAiB,CAAC,CAAA;QAE1E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,CAAA;IAC7D,CAAC;IAED,SAAS,sBAAsB,CAAC,YAAoB;QAElD,MAAM,eAAe,GAAG,0BAA0B,CAAC,GAAG,YAAY,kBAAkB,CAAC,CAAA;QACrF,MAAM,eAAe,GAAG,0BAA0B,CAAC,GAAG,YAAY,kBAAkB,CAAC,CAAA;QACrF,MAAM,eAAe,GAAG,0BAA0B,CAAC,GAAG,YAAY,kBAAkB,CAAC,CAAA;QAErF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,CAAA;IAC9D,CAAC;IAED,OAAO;QACL,iBAAiB;QACjB,0BAA0B;QAC1B,2BAA2B;QAC3B,sBAAsB;KACvB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,SAA4B,EAC5B,aAAqB;IAGrB,MAAM,aAAa,GAAmB,EAAE,CAAA;IAExC,MAAM,EACJ,iBAAiB,EACjB,0BAA0B,EAC1B,2BAA2B,EAC3B,sBAAsB,EACvB,GAAG,iBAAiB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAE/C,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,oBAAoB,CAAC,CAAA;IAClE,MAAM,4BAA4B,GAAG,2BAA2B,CAAC,8BAA8B,CAAC,CAAA;IAChG,MAAM,4BAA4B,GAAG,2BAA2B,CAAC,8BAA8B,CAAC,CAAA;IAEhG,MAAM,UAAU,GAAG;QACjB,OAAO,EAAE,kBAAkB;QAC3B,iBAAiB,EAAE,4BAA4B;QAC/C,iBAAiB,EAAE,4BAA4B;KAChD,CAAA;IAED,MAAM,WAAW,GAAG,EAAE,CAAA;IACtB,KAAK,CAAC,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACzC,WAAW,CAAC,cAAc,GAAG,EAAE,CAAC,GAAG,sBAAsB,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAA;IAC5F,CAAC,CAAC,CAAA;IAEF,MAAM,yBAAyB,GAAG,2BAA2B,CAAC,2BAA2B,CAAC,CAAA;IAC1F,MAAM,wBAAwB,GAAG,0BAA0B,CAAC,0BAA0B,CAAC,CAAA;IAEvF,MAAM,SAAS,GAAG;QAChB,eAAe,EAAE,yBAAyB;QAC1C,cAAc,EAAE,wBAAwB;KACzC,CAAA;IAED,0BAA0B,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAEpD,OAAO,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,aAAa,EAAE,CAAA;AAC1E,CAAC"} \ No newline at end of file diff --git a/build/xception/index.d.ts b/build/xception/index.d.ts new file mode 100644 index 0000000..021d0de --- /dev/null +++ b/build/xception/index.d.ts @@ -0,0 +1 @@ +export * from './TinyXception'; diff --git a/build/xception/index.js b/build/xception/index.js new file mode 100644 index 0000000..0fc246d --- /dev/null +++ b/build/xception/index.js @@ -0,0 +1,2 @@ +export * from './TinyXception'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/xception/index.js.map b/build/xception/index.js.map new file mode 100644 index 0000000..4f5ca3f --- /dev/null +++ b/build/xception/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/xception/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"} \ No newline at end of file diff --git a/build/xception/types.d.ts b/build/xception/types.d.ts new file mode 100644 index 0000000..0d8bddb --- /dev/null +++ b/build/xception/types.d.ts @@ -0,0 +1,23 @@ +import { ConvParams, SeparableConvParams } from '../common'; +export declare type ReductionBlockParams = { + separable_conv0: SeparableConvParams; + separable_conv1: SeparableConvParams; + expansion_conv: ConvParams; +}; +export declare type MainBlockParams = { + separable_conv0: SeparableConvParams; + separable_conv1: SeparableConvParams; + separable_conv2: SeparableConvParams; +}; +export declare type TinyXceptionParams = { + entry_flow: { + conv_in: ConvParams; + reduction_block_0: ReductionBlockParams; + reduction_block_1: ReductionBlockParams; + }; + middle_flow: any; + exit_flow: { + reduction_block: ReductionBlockParams; + separable_conv: SeparableConvParams; + }; +}; diff --git a/build/xception/types.js b/build/xception/types.js new file mode 100644 index 0000000..5b2306a --- /dev/null +++ b/build/xception/types.js @@ -0,0 +1 @@ +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/build/xception/types.js.map b/build/xception/types.js.map new file mode 100644 index 0000000..f62d155 --- /dev/null +++ b/build/xception/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/xception/types.ts"],"names":[],"mappings":""} \ No newline at end of file