forked from WebDevSimplified/Face-Detection-JavaScript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
89 lines (84 loc) · 3.37 KB
/
script.js
File metadata and controls
89 lines (84 loc) · 3.37 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
79
80
81
82
83
84
85
86
87
88
89
const videoFrame = document.getElementById('videoFrame')
const video = document.getElementById('video')
const data = document.getElementById('data')
data.innerHTML = 'DATA';
Promise.all([
faceapi.nets.tinyFaceDetector.loadFromUri('/models'),
faceapi.nets.faceLandmark68Net.loadFromUri('/models'),
faceapi.nets.faceRecognitionNet.loadFromUri('/models'),
faceapi.nets.faceExpressionNet.loadFromUri('/models')
]).then(startVideo)
function startVideo() {
navigator.getUserMedia({
video: {}
},
stream => video.srcObject = stream,
err => console.error(err)
)
}
video.addEventListener('play', () => {
const canvas = faceapi.createCanvasFromMedia(video)
videoFrame.append(canvas)
const displaySize = {
width: video.width,
height: video.height
}
const imagePlaneWidthCm = 26.6;
const focalLenCm = 30.48;
const imagePlaneWidthPx = canvas.width;
const headWidthWorldCm = 14;
const focalLenPx = (imagePlaneWidthPx * focalLenCm) / imagePlaneWidthCm;
faceapi.matchDimensions(canvas, displaySize)
setInterval(async () => {
// const detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions())
// .withFaceLandmarks()
// // .withFaceExpressions()
const detections = await faceapi.detectSingleFace(video, new faceapi.TinyFaceDetectorOptions({
inputSize: 256
// scoreThreshhold: 0.9
}))
.withFaceLandmarks()
// .withFaceExpressions()
if (!detections) {
// data.innerHTML = '-';
return;
}
const resizedDetections = faceapi.resizeResults(detections, displaySize)
canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height)
// faceapi.draw.drawDetections(canvas, resizedDetections)
// const leftEye = resizedDetections[0].getLeftEye()
if (resizedDetections && resizedDetections.detection) {
let leftEye = resizedDetections.landmarks.getLeftEye()[0];
let rightEye = resizedDetections.landmarks.getRightEye()[0];
let nose = resizedDetections.landmarks.getNose()[0];
let jaw = resizedDetections.landmarks.getJawOutline();
let headWidthPx = Math.sqrt(Math.pow(jaw[16]._x - jaw[0]._x, 2) + Math.pow(jaw[16]._y - jaw[0]._y, 2));
// Solve for head Distance
let msg = `
w,h [${canvas.width},${canvas.height}]
Position [${Math.round(nose._x)}px,${Math.round(nose._y)}px]
- on paper [${Math.round(getImagePlaneCm(nose._x))}cm,${Math.round(getImagePlaneCm(nose._y))}cm]
Head width [14cm]
- image [${Math.round(headWidthPx)}px]
- on paper [${Math.round(getImagePlaneCm(headWidthPx))}cm]
- distance [${Math.round(worldPosition(headWidthPx,canvas.width-nose._x))}][${Math.round(worldPosition(headWidthPx,canvas.height-nose._y))}][${Math.round(headWorldDistance(headWidthPx))}cm]
`;
msg = msg.replace(/\n/g, '</br>');
// console.log(jaw);
data.innerHTML = msg;
faceapi.draw.drawFaceLandmarks(canvas, resizedDetections)
} else {
// data.innerHTML = 'x';
}
// faceapi.draw.drawFaceExpressions(canvas, resizedDetections)
}, 1000 / 24)
function getImagePlaneCm(px) {
return (imagePlaneWidthCm * px) / imagePlaneWidthPx;
}
function headWorldDistance(headWidthPx) {
return headWidthWorldCm * focalLenCm / getImagePlaneCm(headWidthPx);
}
function worldPosition(headWidthPx, px) {
return headWidthWorldCm * px / headWidthPx;
}
})