Skip to content

Commit f36fb46

Browse files
some adjustments to new tfjs-image-recognition-base utility
1 parent c44a4c1 commit f36fb46

16 files changed

+50
-67
lines changed

src/classes/FaceDetection.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { Dimensions, ObjectDetection, Rect } from 'tfjs-image-recognition-base';
1+
import { IDimensions, ObjectDetection, Rect } from 'tfjs-image-recognition-base';
22

33
export class FaceDetection extends ObjectDetection {
44
constructor(
55
score: number,
66
relativeBox: Rect,
7-
imageDims: Dimensions
7+
imageDims: IDimensions
88
) {
99
super(score, score, '', relativeBox, imageDims)
1010
}

src/classes/FaceDetectionWithLandmarks.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,22 @@ export class FaceDetectionWithLandmarks {
1414
}
1515

1616
public get detection(): FaceDetection { return this._detection }
17-
1817
public get relativeLandmarks(): FaceLandmarks { return this._relativeLandmarks }
1918

19+
public get alignedRect(): FaceDetection {
20+
const rect = this.landmarks.align()
21+
const { imageDims } = this.detection
22+
return new FaceDetection(this._detection.score, rect.rescale(imageDims.reverse()), imageDims)
23+
}
24+
2025
public get landmarks(): FaceLandmarks {
2126
const { x, y } = this.detection.box
2227
return this._relativeLandmarks.shift(x, y)
2328
}
2429

2530
public forSize(width: number, height: number): FaceDetectionWithLandmarks {
26-
return new FaceDetectionWithLandmarks(
27-
this._detection.forSize(width, height),
28-
this._relativeLandmarks.forSize(width, height)
29-
)
31+
const resizedDetection = this._detection.forSize(width, height)
32+
const resizedLandmarks = this._relativeLandmarks.forSize(resizedDetection.box.width, resizedDetection.box.height)
33+
return new FaceDetectionWithLandmarks(resizedDetection, resizedLandmarks)
3034
}
3135
}

src/classes/FaceLandmarks.ts

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Dimensions, getCenterPoint, Point, Rect } from 'tfjs-image-recognition-base';
1+
import { Dimensions, getCenterPoint, IDimensions, Point, Rect } from 'tfjs-image-recognition-base';
22

33
import { FaceDetection } from './FaceDetection';
44

@@ -8,21 +8,19 @@ const relY = 0.43
88
const relScale = 0.45
99

1010
export class FaceLandmarks {
11-
protected _imageWidth: number
12-
protected _imageHeight: number
1311
protected _shift: Point
14-
protected _faceLandmarks: Point[]
12+
protected _positions: Point[]
13+
protected _imgDims: Dimensions
1514

1615
constructor(
1716
relativeFaceLandmarkPositions: Point[],
18-
imageDims: Dimensions,
17+
imgDims: IDimensions,
1918
shift: Point = new Point(0, 0)
2019
) {
21-
const { width, height } = imageDims
22-
this._imageWidth = width
23-
this._imageHeight = height
20+
const { width, height } = imgDims
21+
this._imgDims = new Dimensions(width, height)
2422
this._shift = shift
25-
this._faceLandmarks = relativeFaceLandmarkPositions.map(
23+
this._positions = relativeFaceLandmarkPositions.map(
2624
pt => pt.mul(new Point(width, height)).add(shift)
2725
)
2826
}
@@ -31,35 +29,26 @@ export class FaceLandmarks {
3129
return new Point(this._shift.x, this._shift.y)
3230
}
3331

34-
public getImageWidth(): number {
35-
return this._imageWidth
36-
}
37-
38-
public getImageHeight(): number {
39-
return this._imageHeight
40-
}
41-
42-
public getPositions(): Point[] {
43-
return this._faceLandmarks
44-
}
45-
46-
public getRelativePositions(): Point[] {
47-
return this._faceLandmarks.map(
48-
pt => pt.sub(this._shift).div(new Point(this._imageWidth, this._imageHeight))
32+
public get imageWidth(): number { return this._imgDims.width }
33+
public get imageHeight(): number { return this._imgDims.height }
34+
public get positions(): Point[] { return this._positions }
35+
public get relativePositions(): Point[] {
36+
return this._positions.map(
37+
pt => pt.sub(this._shift).div(new Point(this.imageWidth, this.imageHeight))
4938
)
5039
}
5140

5241
public forSize<T extends FaceLandmarks>(width: number, height: number): T {
5342
return new (this.constructor as any)(
54-
this.getRelativePositions(),
43+
this.relativePositions,
5544
{ width, height }
5645
)
5746
}
5847

5948
public shift<T extends FaceLandmarks>(x: number, y: number): T {
6049
return new (this.constructor as any)(
61-
this.getRelativePositions(),
62-
{ width: this._imageWidth, height: this._imageHeight },
50+
this.relativePositions,
51+
this._imgDims,
6352
new Point(x, y)
6453
)
6554
}
@@ -84,7 +73,7 @@ export class FaceLandmarks {
8473
): Rect {
8574
if (detection) {
8675
const box = detection instanceof FaceDetection
87-
? detection.getBox().floor()
76+
? detection.box.floor()
8877
: detection
8978

9079
return this.shift(box.x, box.y).align()
@@ -103,7 +92,7 @@ export class FaceLandmarks {
10392
const x = Math.floor(Math.max(0, refPoint.x - (relX * size)))
10493
const y = Math.floor(Math.max(0, refPoint.y - (relY * size)))
10594

106-
return new Rect(x, y, Math.min(size, this._imageWidth + x), Math.min(size, this._imageHeight + y))
95+
return new Rect(x, y, Math.min(size, this.imageWidth + x), Math.min(size, this.imageHeight + y))
10796
}
10897

10998
protected getRefPointsForAlignment(): Point[] {

src/classes/FaceLandmarks5.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { FaceLandmarks } from './FaceLandmarks';
55
export class FaceLandmarks5 extends FaceLandmarks {
66

77
protected getRefPointsForAlignment(): Point[] {
8-
const pts = this.getPositions()
8+
const pts = this.positions
99
return [
1010
pts[0],
1111
pts[1],

src/classes/FaceLandmarks68.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,33 @@ import { getCenterPoint, Point } from 'tfjs-image-recognition-base';
22

33
import { FaceLandmarks } from '../classes/FaceLandmarks';
44

5-
65
export class FaceLandmarks68 extends FaceLandmarks {
76
public getJawOutline(): Point[] {
8-
return this._faceLandmarks.slice(0, 17)
7+
return this.positions.slice(0, 17)
98
}
109

1110
public getLeftEyeBrow(): Point[] {
12-
return this._faceLandmarks.slice(17, 22)
11+
return this.positions.slice(17, 22)
1312
}
1413

1514
public getRightEyeBrow(): Point[] {
16-
return this._faceLandmarks.slice(22, 27)
15+
return this.positions.slice(22, 27)
1716
}
1817

1918
public getNose(): Point[] {
20-
return this._faceLandmarks.slice(27, 36)
19+
return this.positions.slice(27, 36)
2120
}
2221

2322
public getLeftEye(): Point[] {
24-
return this._faceLandmarks.slice(36, 42)
23+
return this.positions.slice(36, 42)
2524
}
2625

2726
public getRightEye(): Point[] {
28-
return this._faceLandmarks.slice(42, 48)
27+
return this.positions.slice(42, 48)
2928
}
3029

3130
public getMouth(): Point[] {
32-
return this._faceLandmarks.slice(48, 68)
31+
return this.positions.slice(48, 68)
3332
}
3433

3534
protected getRefPointsForAlignment(): Point[] {

src/dom/drawLandmarks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ export function drawLandmarks(
4444
// else draw points
4545
const ptOffset = lineWidth / 2
4646
ctx.fillStyle = color
47-
landmarks.getPositions().forEach(pt => ctx.fillRect(pt.x - ptOffset, pt.y - ptOffset, lineWidth, lineWidth))
47+
landmarks.positions.forEach(pt => ctx.fillRect(pt.x - ptOffset, pt.y - ptOffset, lineWidth, lineWidth))
4848
})
4949
}

src/dom/extractFaceTensors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export async function extractFaceTensors(
2727

2828
const boxes = detections.map(
2929
det => det instanceof FaceDetection
30-
? det.forSize(imgWidth, imgHeight).getBox()
30+
? det.forSize(imgWidth, imgHeight).box
3131
: det
3232
)
3333
.map(box => box.clipAtImageBorders(imgWidth, imgHeight))

src/dom/extractFaces.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export async function extractFaces(
3939
const ctx = getContext2dOrThrow(canvas)
4040
const boxes = detections.map(
4141
det => det instanceof FaceDetection
42-
? det.forSize(canvas.width, canvas.height).getBox().floor()
42+
? det.forSize(canvas.width, canvas.height).box.floor()
4343
: det
4444
)
4545
.map(box => box.clipAtImageBorders(canvas.width, canvas.height))

src/faceLandmarkNet/FaceLandmark68NetBase.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as tf from '@tensorflow/tfjs-core';
2-
import { isEven, NetInput, NeuralNetwork, Point, TNetInput, toNetInput, Dimensions } from 'tfjs-image-recognition-base';
2+
import { IDimensions, isEven, NetInput, NeuralNetwork, Point, TNetInput, toNetInput } from 'tfjs-image-recognition-base';
33

44
import { FaceLandmarks68 } from '../classes/FaceLandmarks68';
55

@@ -17,7 +17,7 @@ export class FaceLandmark68NetBase<NetParams> extends NeuralNetwork<NetParams> {
1717
throw new Error(`${this.__name} - runNet not implemented`)
1818
}
1919

20-
public postProcess(output: tf.Tensor2D, inputSize: number, originalDimensions: Dimensions[]): tf.Tensor2D {
20+
public postProcess(output: tf.Tensor2D, inputSize: number, originalDimensions: IDimensions[]): tf.Tensor2D {
2121

2222
const inputDimensions = originalDimensions.map(({ width, height }) => {
2323
const scale = inputSize / Math.max(height, width)

src/globalApi/ComputeFaceDescriptorsTasks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ export class ComputeSingleFaceDescriptorTask extends ComputeFaceDescriptorsTaskB
4141
return
4242
}
4343

44-
const { detection, landmarks } = detectionWithLandmarks
45-
const alignedFaceCanvas = (await extractFaces(this.input, [landmarks.align()]))[0]
44+
const { detection, landmarks, alignedRect } = detectionWithLandmarks
45+
const alignedFaceCanvas = (await extractFaces(this.input, [alignedRect]))[0]
4646
const descriptor = await nets.faceRecognitionNet.computeFaceDescriptor(alignedFaceCanvas) as Float32Array
4747

4848
return new FullFaceDescription(detection, landmarks, descriptor)

src/globalApi/DetectFacesTasks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { MtcnnOptions } from '../mtcnn/MtcnnOptions';
66
import { SsdMobilenetv1Options } from '../ssdMobilenetv1/SsdMobilenetv1Options';
77
import { TinyFaceDetectorOptions } from '../tinyFaceDetector/TinyFaceDetectorOptions';
88
import { ComposableTask } from './ComposableTask';
9-
import { DetectAllFaceLandmarksTask, DetectSingleFaceLandmarksTask } from './DetectFacesLandmarksTasks';
9+
import { DetectAllFaceLandmarksTask, DetectSingleFaceLandmarksTask } from './DetectFaceLandmarksTasks';
1010
import { nets } from './nets';
1111
import { FaceDetectionOptions } from './types';
1212

src/globalApi/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export * from './allFaces'
22
export * from './ComposableTask'
33
export * from './ComputeFaceDescriptorsTasks'
44
export * from './DetectFacesTasks'
5-
export * from './DetectFacesLandmarksTasks'
5+
export * from './DetectFaceLandmarksTasks'
66
export * from './nets'
77
export * from './types'
88

src/mtcnn/Mtcnn.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,6 @@ export class Mtcnn extends NeuralNetwork<NetParams> {
7373
})
7474
.slice(0, maxNumScales)
7575

76-
77-
console.log({
78-
minFaceSize,
79-
scaleFactor,
80-
maxNumScales,
81-
scoreThresholds,
82-
scales
83-
})
84-
8576
stats.scales = scales
8677
stats.pyramid = scales.map(scale => getSizesForScale(scale, [height, width]))
8778

src/mtcnn/MtcnnOptions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ export class MtcnnOptions {
4343
}
4444

4545
if (
46-
!Array.isArray(this._scaleSteps)
47-
|| this._scaleSteps.some(th => typeof th !== 'number')
46+
this._scaleSteps
47+
&& (!Array.isArray(this._scaleSteps) || this._scaleSteps.some(th => typeof th !== 'number'))
4848
) {
4949
throw new Error(`${this._name} - expected scaleSteps to be an array of numbers`)
5050
}

src/mtcnn/extractImagePatches.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import * as tf from '@tensorflow/tfjs-core';
2-
import { Box, createCanvas, Dimensions, getContext2dOrThrow } from 'tfjs-image-recognition-base';
2+
import { Box, createCanvas, getContext2dOrThrow, IDimensions } from 'tfjs-image-recognition-base';
33

44
import { normalize } from './normalize';
55

66
export async function extractImagePatches(
77
img: HTMLCanvasElement,
88
boxes: Box[],
9-
{ width, height }: Dimensions
9+
{ width, height }: IDimensions
1010
): Promise<tf.Tensor4D[]> {
1111

1212

0 commit comments

Comments
 (0)