Skip to content

Commit ba8f84d

Browse files
authored
Create face-detection package from face-landmarks-detection (#965)
* Create face-detection package from face-landmarks-detection * Add keypoints comment * Rename translateOutput function
1 parent b449e79 commit ba8f84d

33 files changed

+6168
-1
lines changed

cloudbuild.yml

+7
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ steps:
4949
args: ['./scripts/run-build.sh', 'deeplab']
5050
waitFor: ['diff']
5151

52+
# Face detection.
53+
- name: 'gcr.io/cloud-builders/gcloud'
54+
entrypoint: 'bash'
55+
id: 'face-detection'
56+
args: ['./scripts/run-build.sh', 'face-detection']
57+
waitFor: ['diff']
58+
5259
# Face landmarks detection.
5360
- name: 'gcr.io/cloud-builders/gcloud'
5461
entrypoint: 'bash'

face-detection/.npmignore

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.DS_Store
2+
.yalc/
3+
.vscode/
4+
.rpt2_cache/
5+
demos/
6+
scripts/
7+
src/
8+
test_data/
9+
coverage/
10+
node_modules/
11+
karma.conf.js
12+
*.tgz
13+
.travis.yml
14+
.npmignore
15+
tslint.json
16+
yarn.lock
17+
yalc.lock
18+
cloudbuild.yml
19+
dist/*_test.js
20+
dist/*_test.js.map
21+
dist/test_util*

face-detection/README.md

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Face Detection
2+
3+
This package provides models for running real-time face detection.
4+
5+
Currently, we provide 1 model option:
6+
7+
#### MediaPipe FaceDetection:
8+
[Demo](https://storage.googleapis.com/tfjs-models/demos/face-detection/index.html?model=mediapipe_face_detection)
9+
10+
MediaPipe FaceDetection can detect multiple faces, each face contains 6 keypoints.
11+
12+
More background information about the package, as well as its performance characteristics on different datasets, can be found here: [Short Range Model Card](https://drive.google.com/file/d/1d4-xJP9PVzOvMBDgIjz6NhvpnlG9_i0S/preview), [Sparse Full Range Model Card](https://drive.google.com/file/d/1aZtpSwsBhA1Epd-ZDfwoQYSTQwEfLm5Z/preview).
13+
14+
-------------------------------------------------------------------------------
15+
## Table of Contents
16+
1. [How to Run It](#how-to-run-it)
17+
2. [Example Code and Demos](#example-code-and-demos)
18+
19+
-------------------------------------------------------------------------------
20+
## How to Run It
21+
In general there are two steps:
22+
23+
You first create a detector by choosing one of the models from `SupportedModels`, including `MediaPipeFaceDetector`.
24+
25+
For example:
26+
27+
```javascript
28+
const model = faceDetection.SupportedModels.MediaPipeFaceDetector;
29+
const detectorConfig = {
30+
runtime: 'mediapipe', // or 'tfjs'
31+
}
32+
const detector = await faceDetection.createDetector(model, detectorConfig);
33+
```
34+
35+
Then you can use the detector to detect faces.
36+
37+
```
38+
const faces = await detector.estimateFaces(image);
39+
```
40+
41+
The returned face list contains detected faces for each face in the image.
42+
If the model cannot detect any faces, the list will be empty.
43+
44+
For each face, it contains a bounding box of the detected face, as well as an array of keypoints. `MediaPipeFaceDetector` returns 6 keypoints.
45+
Each keypoint contains x and y, as well as a name.
46+
47+
Example output:
48+
```
49+
[
50+
{
51+
box: {
52+
xMin: 304.6476503248806,
53+
xMax: 502.5079975897382,
54+
yMin: 102.16298762367356,
55+
yMax: 349.035215984403,
56+
width: 197.86034726485758,
57+
height: 246.87222836072945
58+
},
59+
keypoints: [
60+
{x: 446.544237446397, y: 256.8054528661723, name: "rightEye"},
61+
{x: 406.53152857172876, y: 255.8, "leftEye },
62+
...
63+
],
64+
}
65+
]
66+
```
67+
68+
The `box` represents the bounding box of the face in the image pixel space, with `xMin`, `xMax` denoting the x-bounds, `yMin`, `yMax` denoting the y-bounds, and `width`, `height` are the dimensions of the bounding box.
69+
70+
For the `keypoints`, x and y represent the actual keypoint position in the image pixel space.
71+
72+
The name provides a label for the keypoint, which are 'rightEye', 'leftEye', 'noseTip', 'mouthCenter', 'rightEarTragion', and 'leftEarTragion' respectively.
73+
74+
Refer to each model's documentation for specific configurations for the model
75+
and their performance.
76+
77+
[MediaPipeFaceDetector MediaPipe Documentation](https://github.com/tensorflow/tfjs-models/tree/master/face-detection/src/face_detector_mediapipe)
78+
79+
[MediaPipeFaceDetector TFJS Documentation](https://github.com/tensorflow/tfjs-models/tree/master/face-detection/src/face_detector_tfjs)
80+
81+
## Example Code and Demos
82+
You may reference the demos for code examples. Details for how to run the demos
83+
are included in the `demos/`
84+
[folder](https://github.com/tensorflow/tfjs-models/tree/master/face-detection/demos).

face-detection/cloudbuild.yml

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
steps:
2+
3+
# Install common dependencies.
4+
- name: 'node:12'
5+
id: 'yarn-common'
6+
entrypoint: 'yarn'
7+
args: ['install']
8+
9+
# Install face-detection dependencies.
10+
- name: 'node:12'
11+
dir: 'face-detection'
12+
entrypoint: 'yarn'
13+
id: 'yarn'
14+
args: ['install']
15+
waitFor: ['yarn-common']
16+
17+
# Lint.
18+
- name: 'node:12'
19+
dir: 'face-detection'
20+
entrypoint: 'yarn'
21+
id: 'lint'
22+
args: ['lint']
23+
waitFor: ['yarn']
24+
25+
# Build.
26+
- name: 'node:12'
27+
dir: 'face-detection'
28+
entrypoint: 'yarn'
29+
id: 'build'
30+
args: ['build']
31+
waitFor: ['yarn']
32+
33+
# Run browser tests.
34+
- name: 'node:12'
35+
dir: 'face-detection'
36+
entrypoint: 'yarn'
37+
id: 'test'
38+
args: ['test-ci']
39+
env: ['BROWSERSTACK_USERNAME=deeplearnjs1']
40+
secretEnv: ['BROWSERSTACK_KEY']
41+
waitFor: ['build']
42+
43+
# General configuration
44+
secrets:
45+
- kmsKeyName: projects/learnjs-174218/locations/global/keyRings/tfjs/cryptoKeys/enc
46+
secretEnv:
47+
BROWSERSTACK_KEY: CiQAkwyoIW0LcnxymzotLwaH4udVTQFBEN4AEA5CA+a3+yflL2ASPQAD8BdZnGARf78MhH5T9rQqyz9HNODwVjVIj64CTkFlUCGrP1B2HX9LXHWHLmtKutEGTeFFX9XhuBzNExA=
48+
timeout: 1800s
49+
logsBucket: 'gs://tfjs-build-logs'
50+
substitutions:
51+
_NIGHTLY: ''
52+
options:
53+
logStreamingOption: 'STREAM_ON'
54+
substitution_option: 'ALLOW_LOOSE'

face-detection/karma.conf.js

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/**
2+
* @license
3+
* Copyright 2021 Google LLC. All Rights Reserved.
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
* =============================================================================
16+
*/
17+
18+
const karmaTypescriptConfig = {
19+
tsconfig: 'tsconfig.test.json',
20+
// Disable coverage reports and instrumentation by default for tests
21+
coverageOptions: {instrumentation: false},
22+
reports: {},
23+
bundlerOptions: {
24+
sourceMap: true,
25+
// Process any non es5 code through karma-typescript-es6-transform (babel)
26+
acornOptions: {ecmaVersion: 8},
27+
transforms: [
28+
require('karma-typescript-es6-transform')({
29+
presets: [
30+
// ensure we get es5 by adding IE 11 as a target
31+
['@babel/env', {'targets': {'ie': '11'}, 'loose': true}]
32+
]
33+
}),
34+
]
35+
}
36+
};
37+
38+
const devConfig = {
39+
frameworks: ['jasmine', 'karma-typescript'],
40+
files: [
41+
{pattern: './node_modules/@babel/polyfill/dist/polyfill.js'},
42+
{
43+
// Serve test data as static resources.
44+
pattern: 'test_data/**',
45+
watched: true,
46+
included: false,
47+
served: true,
48+
nocache: true
49+
},
50+
{
51+
// Serve MediaPipe wasm/binarypb/data as static resources.
52+
pattern: './node_modules/@mediapipe/face_detection/**',
53+
watched: true,
54+
included: false,
55+
served: true,
56+
nocache: true
57+
},
58+
'src/setup_test.ts',
59+
{pattern: 'src/**/*.ts'},
60+
],
61+
preprocessors: {'**/*.ts': ['karma-typescript']},
62+
karmaTypescriptConfig,
63+
reporters: ['dots', 'karma-typescript']
64+
};
65+
66+
const browserstackConfig = {
67+
...devConfig,
68+
hostname: 'bs-local.com',
69+
port: 9886
70+
};
71+
72+
module.exports = function(config) {
73+
const args = [];
74+
if (config.testEnv) {
75+
args.push('--testEnv', config.testEnv);
76+
}
77+
if (config.grep) {
78+
args.push('--grep', config.grep);
79+
}
80+
if (config.flags) {
81+
args.push('--flags', config.flags);
82+
}
83+
84+
let extraConfig = null;
85+
86+
if (config.browserstack) {
87+
extraConfig = browserstackConfig;
88+
} else {
89+
extraConfig = devConfig;
90+
}
91+
92+
let exclude = [];
93+
if (config.excludeTest != null) {
94+
exclude.push(config.excludeTest);
95+
}
96+
97+
config.set({
98+
...extraConfig,
99+
singleRun: true,
100+
exclude,
101+
browsers: ['Chrome'],
102+
browserStack: {
103+
username: process.env.BROWSERSTACK_USERNAME,
104+
accessKey: process.env.BROWSERSTACK_KEY,
105+
timeout: 1800,
106+
tunnelIdentifier:
107+
`face_detection_${Date.now()}_${Math.floor(Math.random() * 1000)}`
108+
},
109+
captureTimeout: 3e5,
110+
reportSlowerThan: 500,
111+
browserNoActivityTimeout: 3e5,
112+
browserDisconnectTimeout: 3e5,
113+
browserDisconnectTolerance: 3,
114+
browserSocketTimeout: 1.2e5,
115+
customLaunchers: {
116+
// For browserstack configs see:
117+
// https://www.browserstack.com/automate/node
118+
bs_chrome_mac: {
119+
base: 'BrowserStack',
120+
browser: 'chrome',
121+
browser_version: 'latest',
122+
os: 'OS X',
123+
os_version: 'High Sierra'
124+
},
125+
bs_firefox_mac: {
126+
base: 'BrowserStack',
127+
browser: 'firefox',
128+
browser_version: 'latest',
129+
os: 'OS X',
130+
os_version: 'High Sierra'
131+
},
132+
bs_safari_mac: {
133+
base: 'BrowserStack',
134+
browser: 'safari',
135+
browser_version: 'latest',
136+
os: 'OS X',
137+
os_version: 'High Sierra'
138+
},
139+
bs_ios_11: {
140+
base: 'BrowserStack',
141+
device: 'iPhone X',
142+
os: 'iOS',
143+
os_version: '11.0',
144+
real_mobile: true
145+
},
146+
bs_android_9: {
147+
base: 'BrowserStack',
148+
device: 'Google Pixel 3 XL',
149+
os: 'android',
150+
os_version: '9.0',
151+
real_mobile: true
152+
},
153+
win_10_chrome: {
154+
base: 'BrowserStack',
155+
browser: 'chrome',
156+
// Latest Chrome on Windows has WebGL problems:
157+
// https://github.com/tensorflow/tfjs/issues/2272
158+
browser_version: '77.0',
159+
os: 'Windows',
160+
os_version: '10'
161+
},
162+
},
163+
client: {jasmine: {random: false}, args: args}
164+
})
165+
}

0 commit comments

Comments
 (0)