Skip to content

Commit 89e9691

Browse files
move utility to package
1 parent 4fee52e commit 89e9691

File tree

10 files changed

+231
-133
lines changed

10 files changed

+231
-133
lines changed

examples/public/commons.js

Lines changed: 4 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,6 @@ async function fetchImage(uri) {
1212
return (await axios.get(uri, { responseType: 'blob' })).data
1313
}
1414

15-
function round(num) {
16-
return Math.floor(num * 100) / 100
17-
}
18-
19-
function getElement(arg) {
20-
if (typeof arg === 'string') {
21-
return document.getElementById(arg)
22-
}
23-
return arg
24-
}
25-
2615
async function initFaceDetectionNet() {
2716
const res = await axios.get('face_detection_model.weights', { responseType: 'arraybuffer' })
2817
const weights = new Float32Array(res.data)
@@ -35,115 +24,16 @@ async function initFaceRecognitionNet() {
3524
return facerecognition.faceRecognitionNet(weights)
3625
}
3726

38-
function drawImgToCanvas(canvasArg, imgArg) {
39-
const canvas = getElement(canvasArg)
40-
const img = getElement(imgArg)
41-
canvas.width = img.width
42-
canvas.height = img.height
43-
const ctx = canvas.getContext('2d')
44-
ctx.drawImage(img, 0, 0, img.width, img.height)
45-
return ctx
46-
}
47-
48-
function imgSrcToImageData(src) {
49-
return new Promise((resolve, reject) => {
50-
const img = new Image()
51-
img.onload = function() {
52-
const ctx = drawImgToCanvas(document.createElement('canvas'), img)
53-
resolve(ctx.getImageData(0, 0, img.width, img.height))
54-
}
55-
img.onerror = reject
56-
img.src = src
57-
})
58-
}
59-
60-
function bufferToImgSrc(buf) {
61-
return new Promise((resolve, reject) => {
62-
const reader = new window.FileReader()
63-
reader.onload = () => resolve(reader.result)
64-
reader.onerror = reject
65-
reader.readAsDataURL(buf)
66-
})
67-
}
68-
69-
async function bufferToImageData(buf) {
70-
return imgSrcToImageData(await bufferToImgSrc(buf))
71-
}
72-
73-
function drawBox(canvasArg, x, y, w, h, lineWidth = 2, color = 'blue') {
74-
const canvas = getElement(canvasArg)
75-
const ctx = canvas.getContext('2d')
76-
ctx.strokeStyle = color
77-
ctx.lineWidth = lineWidth
78-
ctx.strokeRect(x, y, w, h)
79-
}
80-
81-
function drawText(canvasArg, x, y, text, fontSize = 20, fontStyle = 'Georgia', color = 'blue') {
82-
const canvas = getElement(canvasArg)
83-
const ctx = canvas.getContext('2d')
84-
ctx.fillStyle = color
85-
ctx.font = fontSize + 'px ' + fontStyle
86-
ctx.fillText(text, x, y)
87-
}
88-
89-
function drawDetection(canvasArg, detection, options = {}) {
90-
const canvas = getElement(canvasArg)
91-
const detectionArray = Array.isArray(detection)
92-
? detection
93-
: [detection]
94-
95-
detectionArray.forEach((det) => {
96-
const {
97-
score,
98-
box
99-
} = det
100-
101-
const {
102-
left,
103-
right,
104-
top,
105-
bottom
106-
} = box
107-
108-
const {
109-
color,
110-
lineWidth = 2,
111-
fontSize = 20,
112-
fontStyle,
113-
withScore = true
114-
} = options
115-
116-
const padText = 2 + lineWidth
117-
118-
drawBox(
119-
canvas,
120-
left,
121-
top,
122-
right - left,
123-
bottom - top,
124-
lineWidth,
125-
color
126-
)
127-
if (withScore) {
128-
drawText(
129-
canvas,
130-
left + padText,
131-
top + (fontSize * 0.6) + padText,
132-
round(score),
133-
fontSize,
134-
fontStyle,
135-
color
136-
)
137-
}
138-
})
139-
}
140-
14127
function renderNavBar(navbarId, exampleUri) {
14228
const examples = [
14329
{
14430
uri: 'face_detection',
14531
name: 'Face Detection'
14632
},
33+
{
34+
uri: 'face_detection_video',
35+
name: 'Face Detection Video'
36+
},
14737
{
14838
uri: 'face_recognition',
14939
name: 'Face Recognition'

examples/public/styles.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
justify-content: center;
1818
align-items: center;
1919
}
20+
.side-by-side >* {
21+
margin: 0 5px;
22+
}
2023

2124
.bold {
2225
font-weight: bold;

examples/server.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ app.use(express.static(path.join(__dirname, './node_modules/axios/dist')))
1212

1313
app.get('/', (req, res) => res.redirect('/face_detection'))
1414
app.get('/face_detection', (req, res) => res.sendFile(path.join(viewsDir, 'faceDetection.html')))
15+
app.get('/face_detection_video', (req, res) => res.sendFile(path.join(viewsDir, 'faceDetectionVideo.html')))
1516
app.get('/face_recognition', (req, res) => res.sendFile(path.join(viewsDir, 'faceRecognition.html')))
1617
app.get('/face_similarity', (req, res) => res.sendFile(path.join(viewsDir, 'faceSimilarity.html')))
1718

examples/views/faceDetection.html

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,26 +45,29 @@
4545
let net, result
4646

4747
function onIncreaseThreshold() {
48-
minConfidence = Math.min(round(minConfidence + 0.1), 1.0)
48+
minConfidence = Math.min(facerecognition.round(minConfidence + 0.1), 1.0)
4949
$('#minConfidence').val(minConfidence)
5050
updateResults()
5151
}
5252

5353
function onDecreaseThreshold() {
54-
minConfidence = Math.max(round(minConfidence - 0.1), 0.1)
54+
minConfidence = Math.max(facerecognition.round(minConfidence - 0.1), 0.1)
5555
$('#minConfidence').val(minConfidence)
5656
updateResults()
5757
}
5858

5959
async function updateResults() {
60-
result = await net.locateFaces(await imgSrcToImageData($(`#img`).get(0).src), minConfidence)
61-
drawImgToCanvas('overlay', 'img')
62-
drawDetection('overlay', result)
60+
result = await net.locateFaces(
61+
await facerecognition.mediaSrcToImageData($(`#img`).get(0).src),
62+
minConfidence
63+
)
64+
facerecognition.drawMediaToCanvas('overlay', 'img')
65+
facerecognition.drawDetection('overlay', result)
6366
}
6467

6568
async function onSelectionChanged(uri) {
6669
const imgBuf = await fetchImage(uri)
67-
$(`#img`).get(0).src = await bufferToImgSrc(imgBuf)
70+
$(`#img`).get(0).src = await facerecognition.bufferToImgSrc(imgBuf)
6871
updateResults()
6972
}
7073

examples/views/faceRecognition.html

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101

102102
function displayTimeStats(timeInMs) {
103103
$('#time').val(`${timeInMs} ms`)
104-
$('#fps').val(`${round(1000 / timeInMs)}`)
104+
$('#fps').val(`${facerecognition.round(1000 / timeInMs)}`)
105105
}
106106

107107
function displayImage(src) {
@@ -111,7 +111,7 @@
111111
async function loadTrainingData(cb) {
112112
return await Promise.all(classes.map(
113113
async className => ({
114-
imgData: await bufferToImageData(
114+
imgData: await facerecognition.bufferToImageData(
115115
await fetchImage(getFaceImageUri(className, 1))
116116
),
117117
className
@@ -123,7 +123,9 @@
123123
return trainDescriptorsByClass
124124
.map(
125125
({ descriptor, className }) => ({
126-
distance: round(facerecognition.euclideanDistance(descriptor, queryDescriptor)),
126+
distance: facerecognition.round(
127+
facerecognition.euclideanDistance(descriptor, queryDescriptor)
128+
),
127129
className
128130
})
129131
)
@@ -134,9 +136,9 @@
134136
async function next() {
135137
const imgBuf = await fetchImage(getFaceImageUri(classes[currClassIdx], currImageIdx))
136138
const imgEl = $('#face').get(0)
137-
imgEl.src = await bufferToImgSrc(imgBuf)
139+
imgEl.src = await facerecognition.bufferToImgSrc(imgBuf)
138140

139-
const imageData = await imgSrcToImageData(imgEl.src)
141+
const imageData = await facerecognition.mediaSrcToImageData(imgEl.src)
140142

141143
const ts = Date.now()
142144
const result = await net.forward(imageData)

examples/views/faceSimilarity.html

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
let net, descriptors = { desc1: null, desc2: null }
4141

4242
function updateResult() {
43-
const distance = round(facerecognition.euclideanDistance(descriptors.desc1, descriptors.desc2))
43+
const distance = facerecognition.round(
44+
facerecognition.euclideanDistance(descriptors.desc1, descriptors.desc2)
45+
)
4446
let text = distance
4547
let bgColor = '#ffffff'
4648
if (distance > threshold) {
@@ -52,13 +54,15 @@
5254
}
5355

5456
async function computeDescriptorFromSrc(imgEl) {
55-
return net.computeFaceDescriptor(await imgSrcToImageData(imgEl.src))
57+
return net.computeFaceDescriptor(
58+
await facerecognition.mediaSrcToImageData(imgEl.src)
59+
)
5660
}
5761

5862
async function onSelectionChanged(which, uri) {
5963
const imgBuf = await fetchImage(uri)
6064
const imgEl = $(`#face${which}`).get(0)
61-
imgEl.src = await bufferToImgSrc(imgBuf)
65+
imgEl.src = await facerecognition.bufferToImgSrc(imgBuf)
6266
descriptors[`desc${which}`] = await computeDescriptorFromSrc(imgEl)
6367
}
6468

src/faceDetectionNet/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { resizeLayer } from './resizeLayer';
77
import { predictionLayer } from './predictionLayer';
88
import { outputLayer } from './outputLayer';
99
import { nonMaxSuppression } from './nonMaxSuppression';
10+
import { FaceDetectionNet } from './types';
1011

1112
function fromData(input: number[]): tf.Tensor4D {
1213
const pxPerChannel = input.length / 3
@@ -78,7 +79,7 @@ export function faceDetectionNet(weights: Float32Array) {
7879
input: ImageData|ImageData[]|number[],
7980
minConfidence: number = 0.8,
8081
maxResults: number = 100,
81-
) {
82+
): Promise<FaceDetectionNet.Detection[]> {
8283
const imgTensor = getImgTensor(input)
8384

8485
const [_, height, width] = imgTensor.shape

src/faceDetectionNet/types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,14 @@ export namespace FaceDetectionNet {
6666
output_layer_params: OutputLayerParams
6767
}
6868

69+
export type Detection = {
70+
score: number
71+
box: {
72+
top: number,
73+
left: number,
74+
right: number,
75+
bottom: number
76+
}
77+
}
78+
6979
}

src/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { euclideanDistance } from './euclideanDistance';
22
import { faceDetectionNet } from './faceDetectionNet';
33
import { faceRecognitionNet } from './faceRecognitionNet';
44
import { normalize } from './normalize';
5-
import * as tf from '@tensorflow/tfjs-core';
65

76
export {
87
euclideanDistance,
98
faceDetectionNet,
109
faceRecognitionNet,
11-
normalize,
12-
tf
13-
}
10+
normalize
11+
}
12+
13+
export * from './utils'

0 commit comments

Comments
 (0)