-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathframe_processing.js
More file actions
78 lines (66 loc) · 2.2 KB
/
Copy pathframe_processing.js
File metadata and controls
78 lines (66 loc) · 2.2 KB
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
importScripts("https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js");
importScripts("https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgpu/dist/tf-backend-webgpu.js");
importScripts("https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm/dist/tf-backend-wasm.js")
importScripts("https://cdn.jsdelivr.net/npm/@tensorflow-models/face-detection")
class FrameProcessor {
async init(options) {
this.width = options.width;
this.height = options.height;
this.offscreen = new OffscreenCanvas(this.width, this.height);
this.ctx = this.offscreen.getContext('2d');
if (!options.hide_faces) {
this.ctx.filter = "contrast(1.4) sepia(0.9)";
}
if (options.hide_faces) {
await tf.setBackend('webgpu');
const model = faceDetection.SupportedModels.MediaPipeFaceDetector;
const detectorConfig = {
runtime: 'tfjs',
//modelType: 'short',
modelType: 'full',
maxFaces: 7,
};
this.detector = await faceDetection.createDetector(model, detectorConfig);
// warm up run
await this.detector.estimateFaces(this.offscreen);
}
self.postMessage({});
}
async processFrame(frame) {
this.ctx.drawImage(frame, 0, 0);
let faces = [];
if (this.detector) {
faces = await this.detector.estimateFaces(this.offscreen);
}
for (let face of faces) {
const box = face.box;
const safety_margin = box.width / 10;
box.xMin -= safety_margin;
box.yMin -= safety_margin;
box.width += 2 * safety_margin;
box.height += 2 * safety_margin;
this.ctx.fillRect(box.xMin, box.yMin, box.width, box.height);
}
this.sendFrame(new VideoFrame(this.offscreen, { timestamp: frame.timestamp }));
frame.close();
}
sendFrame(frame) {
let transfer = frame ? [frame] : null;
self.postMessage(frame, transfer);
}
}
let frame_processor = null;
async function dispatch({command, frame, options}) {
switch (command) {
case 'init': {
frame_processor = new FrameProcessor();
await frame_processor.init(options);
return;
}
case 'frame': {
await frame_processor.processFrame(frame);
return;
}
}
}
self.addEventListener("message", message => dispatch(message.data));