-
Notifications
You must be signed in to change notification settings - Fork 1
/
script.js
101 lines (86 loc) · 2.54 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
let video = document.getElementById('video');
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let faceModel;
let tfliteModel;
let emoji = document.createElement('img');
const emotions = [
'Angry',
'Disgust',
'Fear',
'Happy',
'Sad',
'Surprise',
'Neutral'
];
const emojis = [
'assets/emojis/angry.png',
'assets/emojis/disgust.png',
'assets/emojis/fear.png',
'assets/emojis/happy.png',
'assets/emojis/sad.png',
'assets/emojis/surprise.png',
'assets/emojis/neutral.png'
]
function argMax(array) {
return array.map((x, i) => [x, i]).reduce((r, a) => (a[0] > r[0] ? a : r))[1];
}
const setupWebcam = () => {
navigator.mediaDevices
.getUserMedia({
video: {
width: 300,
height: 300
},
audio: false
})
.then(stream => {
video.srcObject = stream;
});
};
const displayEmojis = async () => {
const prediction = await faceModel.estimateFaces(video, false);
ctx.drawImage(video, 0, 0, 300, 300);
prediction.forEach((pred) => {
ctx.strokeStyle = '#03fc9d';
ctx.lineWidth = 2;
ctx.strokeRect(
pred.topLeft[0],
pred.topLeft[1] - 30,
pred.bottomRight[0] - pred.topLeft[0],
pred.bottomRight[1] - pred.topLeft[1] + 30
);
const img = tf.browser
.fromPixels(video);
const crop = img.slice(
[
Math.floor(pred.topLeft[1] - 30),
Math.floor(pred.topLeft[0])
],
[
Math.floor(pred.bottomRight[1] - pred.topLeft[1] + 30),
Math.floor(pred.bottomRight[0] - pred.topLeft[0])
])
.expandDims()
.resizeNearestNeighbor([48, 48])
.mean(3)
.expandDims(-1);
const outputTensor = tfliteModel.predict(crop);
const emotion = Array.from((outputTensor.dataSync()));
const prediction = argMax(emotion);
emoji.src = emojis[prediction];
const scale = Math.floor((pred.bottomRight[0] - pred.topLeft[0]) / 4);
ctx.drawImage(
emoji,
Math.floor(pred.bottomRight[0] - scale - 3),
Math.floor(pred.topLeft[1] - 27),
scale, scale
);
});
};
setupWebcam();
video.addEventListener('loadeddata', async () => {
faceModel = await blazeface.load();
tfliteModel = await tflite.loadTFLiteModel('assets/tf_model.tflite');
setInterval(displayEmojis, 100);
});