Skip to content

Commit df5ac5d

Browse files
improved drawing api
1 parent 2d885bb commit df5ac5d

25 files changed

+297
-279
lines changed

package-lock.json

Lines changed: 24 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@
1414
"test": "karma start",
1515
"test-browser": "karma start --single-run",
1616
"test-node": "ts-node node_modules/jasmine/bin/jasmine --config=jasmine-node.js",
17-
"test-all": "npm run test-browser && npm run test-node",
17+
"test-all": "npm run test-browser-exclude-uncompressed && npm run test-node-exclude-uncompressed",
18+
"test-all-include-uncompressed": "npm run test-browser && npm run test-node",
1819
"test-facelandmarknets": "set UUT=faceLandmarkNet&& karma start",
1920
"test-facerecognitionnet": "set UUT=faceRecognitionNet&& karma start",
2021
"test-ssdmobilenetv1": "set UUT=ssdMobilenetv1&& karma start",
2122
"test-tinyfacedetector": "set UUT=tinyFaceDetector&& karma start",
2223
"test-mtcnn": "set UUT=mtcnn&& karma start",
2324
"test-cpu": "set BACKEND_CPU=true&& karma start",
2425
"test-exclude-uncompressed": "set EXCLUDE_UNCOMPRESSED=true&& karma start",
26+
"test-browser-exclude-uncompressed": "set EXCLUDE_UNCOMPRESSED=true&& karma start --single-run",
2527
"test-node-exclude-uncompressed": "set EXCLUDE_UNCOMPRESSED=true&& ts-node node_modules/jasmine/bin/jasmine --config=jasmine-node.js",
2628
"docs": "typedoc --options ./typedoc.config.js ./src"
2729
},
@@ -36,7 +38,7 @@
3638
"license": "MIT",
3739
"dependencies": {
3840
"@tensorflow/tfjs-core": "1.0.3",
39-
"tfjs-image-recognition-base": "^0.5.1",
41+
"tfjs-image-recognition-base": "^0.6.0",
4042
"tslib": "^1.9.3"
4143
},
4244
"devDependencies": {

src/classes/FaceDetection.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export class FaceDetection extends ObjectDetection implements IFaceDetecion {
1515
}
1616

1717
public forSize(width: number, height: number): FaceDetection {
18-
return super.forSize(width, height)
18+
const { score, relativeBox, imageDims } = super.forSize(width, height)
19+
return new FaceDetection(score, relativeBox, imageDims)
1920
}
2021
}

src/dom/drawFaceExpressions.ts

Lines changed: 0 additions & 59 deletions
This file was deleted.

src/dom/drawLandmarks.ts

Lines changed: 0 additions & 49 deletions
This file was deleted.

src/dom/index.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,2 @@
1-
export * from './drawContour'
2-
export * from './drawLandmarks'
3-
export * from './drawFaceExpressions'
41
export * from './extractFaces'
5-
export * from './extractFaceTensors'
6-
export * from './types'
2+
export * from './extractFaceTensors'

src/dom/types.ts

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/draw/DrawFaceLandmarks.ts

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { getContext2dOrThrow, IPoint } from 'tfjs-image-recognition-base';
2+
3+
import { FaceLandmarks } from '../classes/FaceLandmarks';
4+
import { FaceLandmarks68 } from '../classes/FaceLandmarks68';
5+
import { WithFaceDetection } from '../factories/WithFaceDetection';
6+
import { isWithFaceLandmarks, WithFaceLandmarks } from '../factories/WithFaceLandmarks';
7+
import { drawContour } from './drawContour';
8+
9+
export interface IDrawFaceLandmarksOptions {
10+
drawLines?: boolean
11+
drawPoints?: boolean
12+
lineWidth?: number
13+
pointSize?: number
14+
lineColor?: string
15+
pointColor?: string
16+
}
17+
18+
export class DrawFaceLandmarksOptions {
19+
public drawLines: boolean
20+
public drawPoints: boolean
21+
public lineWidth: number
22+
public pointSize: number
23+
public lineColor: string
24+
public pointColor: string
25+
26+
constructor(options: IDrawFaceLandmarksOptions = {}) {
27+
const { drawLines = true, drawPoints = true, lineWidth, lineColor, pointSize, pointColor } = options
28+
this.drawLines = drawLines
29+
this.drawPoints = drawPoints
30+
this.lineWidth = lineWidth || 1
31+
this.pointSize = pointSize || 2
32+
this.lineColor = lineColor || 'rgba(0, 255, 255, 1)'
33+
this.pointColor = pointColor || 'rgba(255, 0, 255, 1)'
34+
}
35+
}
36+
37+
export class DrawFaceLandmarks {
38+
public faceLandmarks: FaceLandmarks
39+
public options: DrawFaceLandmarksOptions
40+
41+
constructor(
42+
faceLandmarks: FaceLandmarks,
43+
options: IDrawFaceLandmarksOptions = {}
44+
) {
45+
this.faceLandmarks = faceLandmarks
46+
this.options = new DrawFaceLandmarksOptions(options)
47+
}
48+
49+
draw(canvasArg: string | HTMLCanvasElement | CanvasRenderingContext2D) {
50+
const ctx = getContext2dOrThrow(canvasArg)
51+
52+
const { drawLines, drawPoints, lineWidth, lineColor, pointSize, pointColor } = this.options
53+
54+
if (drawLines && this.faceLandmarks instanceof FaceLandmarks68) {
55+
ctx.strokeStyle = lineColor
56+
ctx.lineWidth = lineWidth
57+
drawContour(ctx, this.faceLandmarks.getJawOutline())
58+
drawContour(ctx, this.faceLandmarks.getLeftEyeBrow())
59+
drawContour(ctx, this.faceLandmarks.getRightEyeBrow())
60+
drawContour(ctx, this.faceLandmarks.getNose())
61+
drawContour(ctx, this.faceLandmarks.getLeftEye(), true)
62+
drawContour(ctx, this.faceLandmarks.getRightEye(), true)
63+
drawContour(ctx, this.faceLandmarks.getMouth(), true)
64+
}
65+
66+
if (drawPoints) {
67+
ctx.strokeStyle = pointColor
68+
ctx.fillStyle = pointColor
69+
70+
const drawPoint = (pt: IPoint) => {
71+
ctx.beginPath()
72+
ctx.arc(pt.x, pt.y, pointSize, 0, 2 * Math.PI)
73+
ctx.fill()
74+
}
75+
this.faceLandmarks.positions.forEach(drawPoint)
76+
}
77+
}
78+
}
79+
80+
export type DrawFaceLandmarksInput = FaceLandmarks | WithFaceLandmarks<WithFaceDetection<{}>>
81+
82+
export function drawFaceLandmarks(
83+
canvasArg: string | HTMLCanvasElement,
84+
faceLandmarks: DrawFaceLandmarksInput | Array<DrawFaceLandmarksInput>
85+
) {
86+
const faceLandmarksArray = Array.isArray(faceLandmarks) ? faceLandmarks : [faceLandmarks]
87+
faceLandmarksArray.forEach(f => {
88+
const landmarks = f instanceof FaceLandmarks
89+
? f
90+
: (isWithFaceLandmarks(f) ? f.landmarks : undefined)
91+
if (!landmarks) {
92+
throw new Error('drawFaceLandmarks - expected faceExpressions to be FaceLandmarks | WithFaceLandmarks<WithFaceDetection<{}>> or array thereof')
93+
}
94+
95+
new DrawFaceLandmarks(landmarks).draw(canvasArg)
96+
})
97+
}
File renamed without changes.

0 commit comments

Comments
 (0)