fix and optimize for mobile platform

pull/134/head
Vladimir Mandic 2021-05-28 10:43:48 -04:00
parent e24adc95f3
commit 82c93191ac
14 changed files with 118 additions and 118 deletions

View File

@ -9,11 +9,12 @@ Repository: **<git+https://github.com/vladmandic/human.git>**
## Changelog
### **HEAD -> main** 2021/05/27 mandic00@live.com
### **1.9.4** 2021/05/27 mandic00@live.com
### **origin/main** 2021/05/26 mandic00@live.com
- fix demo facecompare
- webhint and lighthouse optimizations
- add camera startup diag messages
- implemented unified result.persons that combines face, body and hands for each person

View File

@ -75,10 +75,10 @@
<div id="loader" class="loader"></div>
<div id="status" class="status"></div>
<div id="menubar" class="menubar">
<div id="btnDisplay" class="icon"><div class="icon-binoculars"> </div>display options</div>
<div id="btnImage" class="icon"><div class="icon-brush"></div>image processing</div>
<div id="btnProcess" class="icon"><div class="icon-stats"></div>model processing</div>
<div id="btnModel" class="icon"><div class="icon-games"></div>model selection</div>
<div id="btnDisplay" class="icon"><div class="icon-binoculars"> </div>display</div>
<div id="btnImage" class="icon"><div class="icon-brush"></div>input</div>
<div id="btnProcess" class="icon"><div class="icon-stats"></div>options</div>
<div id="btnModel" class="icon"><div class="icon-games"></div>models</div>
<div id="btnStart" class="icon"><div class="icon-webcam"></div><span id="btnStartText">start video</span></div>
</div>
<div id="media">

View File

@ -16,7 +16,6 @@ let human;
const userConfig = {
warmup: 'none',
/*
backend: 'webgl',
async: false,
cacheSensitivity: 0,
@ -31,12 +30,11 @@ const userConfig = {
description: { enabled: false },
emotion: { enabled: false },
},
hand: { enabled: true },
body: { enabled: true, modelPath: 'posenet.json' },
hand: { enabled: false },
body: { enabled: false, modelPath: 'posenet.json' },
// body: { enabled: true, modelPath: 'blazepose.json' },
object: { enabled: false },
gesture: { enabled: true },
*/
};
const drawOptions = {
@ -48,7 +46,7 @@ const drawOptions = {
const ui = {
// configurable items
console: true, // log messages to browser console
crop: true, // video mode crop to size or leave full frame
crop: false, // video mode crop to size or leave full frame
facing: true, // camera facing front or back
baseBackground: 'rgba(50, 50, 50, 1)', // 'grey'
columns: 2, // when processing sample images create this many columns
@ -305,23 +303,23 @@ async function setupCamera() {
ui.busy = false;
return msg;
}
// enumerate devices for diag purposes
if (initialCameraAccess) {
const devices = await navigator.mediaDevices.enumerateDevices();
log('enumerated devices:');
for (const device of devices) log(` kind:${device.kind} label:${device.label} id:${device.deviceId}`);
}
let stream;
const constraints = {
audio: false,
video: {
facingMode: ui.facing ? 'user' : 'environment',
resizeMode: ui.crop ? 'crop-and-scale' : 'none',
width: { ideal: document.body.clientWidth },
// height: { ideal: document.body.clientHeight }, // not set as we're using aspectRation to get height instead
aspectRatio: document.body.clientWidth / document.body.clientHeight,
// deviceId: 'xxxx' // if you have multiple webcams, specify one to use explicitly
},
};
if (window.innerWidth > window.innerHeight) constraints.video.width = { ideal: window.innerWidth };
else constraints.video.height = { ideal: (window.innerHeight - document.getElementById('menubar').offsetHeight) };
// enumerate devices for diag purposes
if (initialCameraAccess) {
navigator.mediaDevices.enumerateDevices().then((devices) => log('enumerated devices:', devices));
log('camera constraints', constraints);
}
try {
stream = await navigator.mediaDevices.getUserMedia(constraints);
} catch (err) {
@ -334,37 +332,24 @@ async function setupCamera() {
ui.busy = false;
return msg;
}
if (stream) video.srcObject = stream;
else {
ui.busy = false;
return 'camera stream empty';
}
const tracks = stream.getVideoTracks();
if (tracks && tracks.length >= 1) {
if (tracks.length > 1) {
log('enumerated viable tracks:', tracks.length);
for (const t of tracks) log(` ${t.kind}: ${t.label}`);
}
if (initialCameraAccess) log('enumerated viable tracks:', tracks);
} else {
ui.busy = false;
return 'no camera track';
}
const track = stream.getVideoTracks()[0];
const settings = track.getSettings();
if (initialCameraAccess) log('selected camera:', track.label, 'id:', settings.deviceId);
// log('camera constraints:', constraints, 'window:', { width: window.innerWidth, height: window.innerHeight }, 'settings:', settings, 'track:', track);
ui.camera = { name: track.label.toLowerCase(), width: settings.width, height: settings.height, facing: settings.facingMode === 'user' ? 'front' : 'back' };
if (initialCameraAccess) log('selected video source:', track, settings); // log('selected camera:', track.label, 'id:', settings.deviceId);
ui.camera = { name: track.label.toLowerCase(), width: video.videoWidth, height: video.videoHeight, facing: settings.facingMode === 'user' ? 'front' : 'back' };
initialCameraAccess = false;
return new Promise((resolve) => {
video.onloadeddata = async () => {
video.width = video.videoWidth;
video.height = video.videoHeight;
canvas.width = video.width;
canvas.height = video.height;
canvas.style.width = canvas.width > canvas.height ? '100vw' : '';
canvas.style.height = canvas.width > canvas.height ? '' : '100vh';
ui.menuWidth.input.setAttribute('value', video.width);
ui.menuHeight.input.setAttribute('value', video.height);
const promise = !stream || new Promise((resolve) => {
video.onloadeddata = () => {
if (settings.width > settings.height) canvas.style.width = '100vw';
else canvas.style.height = '100vh';
ui.menuWidth.input.setAttribute('value', video.videoWidth);
ui.menuHeight.input.setAttribute('value', video.videoHeight);
if (live) video.play();
// eslint-disable-next-line no-use-before-define
if (live && !ui.detectThread) runHumanDetect(video, canvas);
@ -372,6 +357,13 @@ async function setupCamera() {
resolve();
};
});
// attach input to video element
if (stream) {
video.srcObject = stream;
return promise;
}
ui.busy = false;
return 'camera stream empty';
}
function initPerfMonitor() {
@ -645,7 +637,9 @@ function setupMenu() {
async function resize() {
window.onresize = null;
const viewportScale = 1; // Math.min(1, Math.round(100 * window.innerWidth / 960) / 100);
// best setting for mobile, ignored for desktop
// can set dynamic value such as Math.min(1, Math.round(100 * window.innerWidth / 960) / 100);
const viewportScale = 0.7;
if (!ui.viewportSet) {
const viewport = document.querySelector('meta[name=viewport]');
viewport.setAttribute('content', `width=device-width, shrink-to-fit=yes, minimum-scale=0.2, maximum-scale=2.0, user-scalable=yes, initial-scale=${viewportScale}`);
@ -664,10 +658,10 @@ async function resize() {
menu.process.menu.style.left = x[2];
menu.models.menu.style.left = x[3];
const fontSize = Math.trunc(10 * (1 - viewportScale)) + 16;
const fontSize = Math.trunc(10 * (1 - viewportScale)) + 14;
document.documentElement.style.fontSize = `${fontSize}px`;
human.draw.options.font = `small-caps ${fontSize + 4}px "Segoe UI"`;
human.draw.options.font = `small-caps ${fontSize}px "Segoe UI"`;
human.draw.options.lineHeight = fontSize + 2;
await setupCamera();
window.onresize = resize;
@ -686,7 +680,7 @@ async function main() {
window.addEventListener('unhandledrejection', (evt) => {
// eslint-disable-next-line no-console
console.error(evt.reason || evt);
document.getElementById('log').innerHTML = evt?.reason?.message || evt?.reason || evt;
document.getElementById('log').innerHTML = evt.reason.message || evt.reason || evt;
status('exception error');
evt.preventDefault();
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/human.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/human.js vendored

File diff suppressed because one or more lines are too long

View File

@ -17525,24 +17525,25 @@ var iris = (res) => {
center = true;
gestures.push({ iris: i, gesture: "facing center" });
}
const rightIrisCenterX = Math.abs(res[i].mesh[33][0] - res[i].annotations.rightEyeIris[0][0]) / res[i].annotations.rightEyeIris[0][0];
const leftIrisCenterX = Math.abs(res[i].mesh[263][0] - res[i].annotations.leftEyeIris[0][0]) / res[i].annotations.leftEyeIris[0][0];
if (leftIrisCenterX > 0.033 || rightIrisCenterX > 0.033)
const rightIrisCenterX = Math.abs(res[i].mesh[33][0] - res[i].annotations.rightEyeIris[0][0]) / res[i].box[2];
const leftIrisCenterX = Math.abs(res[i].mesh[263][0] - res[i].annotations.leftEyeIris[0][0]) / res[i].box[2];
if (leftIrisCenterX > 0.06 || rightIrisCenterX > 0.06)
center = false;
if (leftIrisCenterX > 0.033)
if (leftIrisCenterX > 0.06)
gestures.push({ iris: i, gesture: "looking right" });
if (rightIrisCenterX > 0.033)
if (rightIrisCenterX > 0.06)
gestures.push({ iris: i, gesture: "looking left" });
const rightIrisCenterY = Math.abs(res[i].mesh[145][1] - res[i].annotations.rightEyeIris[0][1]) / res[i].annotations.rightEyeIris[0][1];
const leftIrisCenterY = Math.abs(res[i].mesh[374][1] - res[i].annotations.leftEyeIris[0][1]) / res[i].annotations.leftEyeIris[0][1];
if (leftIrisCenterY < 0.015 || rightIrisCenterY < 0.015 || leftIrisCenterY > 0.03 || rightIrisCenterY > 0.03)
const rightIrisCenterY = Math.abs(res[i].mesh[145][1] - res[i].annotations.rightEyeIris[0][1]) / res[i].box[3];
const leftIrisCenterY = Math.abs(res[i].mesh[374][1] - res[i].annotations.leftEyeIris[0][1]) / res[i].box[3];
if (leftIrisCenterY < 0.01 || rightIrisCenterY < 0.01 || leftIrisCenterY > 0.025 || rightIrisCenterY > 0.025)
center = false;
if (leftIrisCenterY < 0.015 || rightIrisCenterY < 0.015)
if (leftIrisCenterY < 0.01 || rightIrisCenterY < 0.01)
gestures.push({ iris: i, gesture: "looking down" });
if (leftIrisCenterY > 0.03 || rightIrisCenterY > 0.03)
if (leftIrisCenterY > 0.025 || rightIrisCenterY > 0.025)
gestures.push({ iris: i, gesture: "looking up" });
if (center)
gestures.push({ iris: i, gesture: "looking center" });
console.log(leftIrisCenterX, rightIrisCenterX, leftIrisCenterY, rightIrisCenterY, gestures);
}
return gestures;
};
@ -18427,7 +18428,7 @@ var options = {
color: "rgba(173, 216, 230, 0.3)",
labelColor: "rgba(173, 216, 230, 1)",
shadowColor: "black",
font: 'small-caps 16px "Segoe UI"',
font: 'small-caps 14px "Segoe UI"',
lineHeight: 24,
lineWidth: 6,
pointSize: 2,

View File

@ -17526,24 +17526,25 @@ var iris = (res) => {
center = true;
gestures.push({ iris: i, gesture: "facing center" });
}
const rightIrisCenterX = Math.abs(res[i].mesh[33][0] - res[i].annotations.rightEyeIris[0][0]) / res[i].annotations.rightEyeIris[0][0];
const leftIrisCenterX = Math.abs(res[i].mesh[263][0] - res[i].annotations.leftEyeIris[0][0]) / res[i].annotations.leftEyeIris[0][0];
if (leftIrisCenterX > 0.033 || rightIrisCenterX > 0.033)
const rightIrisCenterX = Math.abs(res[i].mesh[33][0] - res[i].annotations.rightEyeIris[0][0]) / res[i].box[2];
const leftIrisCenterX = Math.abs(res[i].mesh[263][0] - res[i].annotations.leftEyeIris[0][0]) / res[i].box[2];
if (leftIrisCenterX > 0.06 || rightIrisCenterX > 0.06)
center = false;
if (leftIrisCenterX > 0.033)
if (leftIrisCenterX > 0.06)
gestures.push({ iris: i, gesture: "looking right" });
if (rightIrisCenterX > 0.033)
if (rightIrisCenterX > 0.06)
gestures.push({ iris: i, gesture: "looking left" });
const rightIrisCenterY = Math.abs(res[i].mesh[145][1] - res[i].annotations.rightEyeIris[0][1]) / res[i].annotations.rightEyeIris[0][1];
const leftIrisCenterY = Math.abs(res[i].mesh[374][1] - res[i].annotations.leftEyeIris[0][1]) / res[i].annotations.leftEyeIris[0][1];
if (leftIrisCenterY < 0.015 || rightIrisCenterY < 0.015 || leftIrisCenterY > 0.03 || rightIrisCenterY > 0.03)
const rightIrisCenterY = Math.abs(res[i].mesh[145][1] - res[i].annotations.rightEyeIris[0][1]) / res[i].box[3];
const leftIrisCenterY = Math.abs(res[i].mesh[374][1] - res[i].annotations.leftEyeIris[0][1]) / res[i].box[3];
if (leftIrisCenterY < 0.01 || rightIrisCenterY < 0.01 || leftIrisCenterY > 0.025 || rightIrisCenterY > 0.025)
center = false;
if (leftIrisCenterY < 0.015 || rightIrisCenterY < 0.015)
if (leftIrisCenterY < 0.01 || rightIrisCenterY < 0.01)
gestures.push({ iris: i, gesture: "looking down" });
if (leftIrisCenterY > 0.03 || rightIrisCenterY > 0.03)
if (leftIrisCenterY > 0.025 || rightIrisCenterY > 0.025)
gestures.push({ iris: i, gesture: "looking up" });
if (center)
gestures.push({ iris: i, gesture: "looking center" });
console.log(leftIrisCenterX, rightIrisCenterX, leftIrisCenterY, rightIrisCenterY, gestures);
}
return gestures;
};
@ -18428,7 +18429,7 @@ var options = {
color: "rgba(173, 216, 230, 0.3)",
labelColor: "rgba(173, 216, 230, 1)",
shadowColor: "black",
font: 'small-caps 16px "Segoe UI"',
font: 'small-caps 14px "Segoe UI"',
lineHeight: 24,
lineWidth: 6,
pointSize: 2,

23
dist/human.node.js vendored
View File

@ -17525,24 +17525,25 @@ var iris = (res) => {
center = true;
gestures.push({ iris: i, gesture: "facing center" });
}
const rightIrisCenterX = Math.abs(res[i].mesh[33][0] - res[i].annotations.rightEyeIris[0][0]) / res[i].annotations.rightEyeIris[0][0];
const leftIrisCenterX = Math.abs(res[i].mesh[263][0] - res[i].annotations.leftEyeIris[0][0]) / res[i].annotations.leftEyeIris[0][0];
if (leftIrisCenterX > 0.033 || rightIrisCenterX > 0.033)
const rightIrisCenterX = Math.abs(res[i].mesh[33][0] - res[i].annotations.rightEyeIris[0][0]) / res[i].box[2];
const leftIrisCenterX = Math.abs(res[i].mesh[263][0] - res[i].annotations.leftEyeIris[0][0]) / res[i].box[2];
if (leftIrisCenterX > 0.06 || rightIrisCenterX > 0.06)
center = false;
if (leftIrisCenterX > 0.033)
if (leftIrisCenterX > 0.06)
gestures.push({ iris: i, gesture: "looking right" });
if (rightIrisCenterX > 0.033)
if (rightIrisCenterX > 0.06)
gestures.push({ iris: i, gesture: "looking left" });
const rightIrisCenterY = Math.abs(res[i].mesh[145][1] - res[i].annotations.rightEyeIris[0][1]) / res[i].annotations.rightEyeIris[0][1];
const leftIrisCenterY = Math.abs(res[i].mesh[374][1] - res[i].annotations.leftEyeIris[0][1]) / res[i].annotations.leftEyeIris[0][1];
if (leftIrisCenterY < 0.015 || rightIrisCenterY < 0.015 || leftIrisCenterY > 0.03 || rightIrisCenterY > 0.03)
const rightIrisCenterY = Math.abs(res[i].mesh[145][1] - res[i].annotations.rightEyeIris[0][1]) / res[i].box[3];
const leftIrisCenterY = Math.abs(res[i].mesh[374][1] - res[i].annotations.leftEyeIris[0][1]) / res[i].box[3];
if (leftIrisCenterY < 0.01 || rightIrisCenterY < 0.01 || leftIrisCenterY > 0.025 || rightIrisCenterY > 0.025)
center = false;
if (leftIrisCenterY < 0.015 || rightIrisCenterY < 0.015)
if (leftIrisCenterY < 0.01 || rightIrisCenterY < 0.01)
gestures.push({ iris: i, gesture: "looking down" });
if (leftIrisCenterY > 0.03 || rightIrisCenterY > 0.03)
if (leftIrisCenterY > 0.025 || rightIrisCenterY > 0.025)
gestures.push({ iris: i, gesture: "looking up" });
if (center)
gestures.push({ iris: i, gesture: "looking center" });
console.log(leftIrisCenterX, rightIrisCenterX, leftIrisCenterY, rightIrisCenterY, gestures);
}
return gestures;
};
@ -18427,7 +18428,7 @@ var options = {
color: "rgba(173, 216, 230, 0.3)",
labelColor: "rgba(173, 216, 230, 1)",
shadowColor: "black",
font: 'small-caps 16px "Segoe UI"',
font: 'small-caps 14px "Segoe UI"',
lineHeight: 24,
lineWidth: 6,
pointSize: 2,

View File

@ -1,17 +1,17 @@
2021-05-27 16:05:26 INFO:  @vladmandic/human version 1.9.4
2021-05-27 16:05:26 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.0.0
2021-05-27 16:05:26 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true}
2021-05-27 16:05:26 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":102,"outputBytes":1292,"outputFiles":"dist/tfjs.esm.js"}
2021-05-27 16:05:26 STATE: Build for: node type: node: {"imports":37,"importBytes":431050,"outputBytes":385549,"outputFiles":"dist/human.node.js"}
2021-05-27 16:05:26 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":110,"outputBytes":1300,"outputFiles":"dist/tfjs.esm.js"}
2021-05-27 16:05:26 STATE: Build for: nodeGPU type: node: {"imports":37,"importBytes":431058,"outputBytes":385553,"outputFiles":"dist/human.node-gpu.js"}
2021-05-27 16:05:26 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":149,"outputBytes":1367,"outputFiles":"dist/tfjs.esm.js"}
2021-05-27 16:05:26 STATE: Build for: nodeWASM type: node: {"imports":37,"importBytes":431125,"outputBytes":385625,"outputFiles":"dist/human.node-wasm.js"}
2021-05-27 16:05:26 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2478,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"}
2021-05-27 16:05:26 STATE: Build for: browserNoBundle type: esm: {"imports":37,"importBytes":431152,"outputBytes":236268,"outputFiles":"dist/human.esm-nobundle.js"}
2021-05-27 16:05:27 STATE: Build for: browserBundle type: tfjs: {"modules":1274,"moduleBytes":4114813,"imports":7,"importBytes":2478,"outputBytes":1111414,"outputFiles":"dist/tfjs.esm.js"}
2021-05-27 16:05:27 STATE: Build for: browserBundle type: iife: {"imports":37,"importBytes":1541172,"outputBytes":1344154,"outputFiles":"dist/human.js"}
2021-05-27 16:05:28 STATE: Build for: browserBundle type: esm: {"imports":37,"importBytes":1541172,"outputBytes":1344146,"outputFiles":"dist/human.esm.js"}
2021-05-27 16:05:28 INFO:  Generate types: ["src/human.ts"]
2021-05-27 16:05:33 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"]
2021-05-27 16:05:33 INFO:  Generate TypeDocs: ["src/human.ts"]
2021-05-28 10:43:13 INFO:  @vladmandic/human version 1.9.4
2021-05-28 10:43:13 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.0.0
2021-05-28 10:43:13 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true}
2021-05-28 10:43:13 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":102,"outputBytes":1292,"outputFiles":"dist/tfjs.esm.js"}
2021-05-28 10:43:13 STATE: Build for: node type: node: {"imports":37,"importBytes":431046,"outputBytes":385548,"outputFiles":"dist/human.node.js"}
2021-05-28 10:43:13 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":110,"outputBytes":1300,"outputFiles":"dist/tfjs.esm.js"}
2021-05-28 10:43:13 STATE: Build for: nodeGPU type: node: {"imports":37,"importBytes":431054,"outputBytes":385552,"outputFiles":"dist/human.node-gpu.js"}
2021-05-28 10:43:13 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":149,"outputBytes":1367,"outputFiles":"dist/tfjs.esm.js"}
2021-05-28 10:43:13 STATE: Build for: nodeWASM type: node: {"imports":37,"importBytes":431121,"outputBytes":385624,"outputFiles":"dist/human.node-wasm.js"}
2021-05-28 10:43:13 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2478,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"}
2021-05-28 10:43:13 STATE: Build for: browserNoBundle type: esm: {"imports":37,"importBytes":431148,"outputBytes":236193,"outputFiles":"dist/human.esm-nobundle.js"}
2021-05-28 10:43:14 STATE: Build for: browserBundle type: tfjs: {"modules":1274,"moduleBytes":4114813,"imports":7,"importBytes":2478,"outputBytes":1111414,"outputFiles":"dist/tfjs.esm.js"}
2021-05-28 10:43:14 STATE: Build for: browserBundle type: iife: {"imports":37,"importBytes":1541168,"outputBytes":1344079,"outputFiles":"dist/human.js"}
2021-05-28 10:43:15 STATE: Build for: browserBundle type: esm: {"imports":37,"importBytes":1541168,"outputBytes":1344071,"outputFiles":"dist/human.esm.js"}
2021-05-28 10:43:15 INFO:  Generate types: ["src/human.ts"]
2021-05-28 10:43:20 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"]
2021-05-28 10:43:20 INFO:  Generate TypeDocs: ["src/human.ts"]

View File

@ -51,7 +51,7 @@ export const options: DrawOptions = {
color: <string>'rgba(173, 216, 230, 0.3)', // 'lightblue' with light alpha channel
labelColor: <string>'rgba(173, 216, 230, 1)', // 'lightblue' with dark alpha channel
shadowColor: <string>'black',
font: <string>'small-caps 16px "Segoe UI"',
font: <string>'small-caps 14px "Segoe UI"',
lineHeight: <number>24,
lineWidth: <number>6,
pointSize: <number>2,

View File

@ -65,20 +65,22 @@ export const iris = (res): Gesture[] => {
gestures.push({ iris: i, gesture: 'facing center' });
}
const rightIrisCenterX = Math.abs(res[i].mesh[33][0] - res[i].annotations.rightEyeIris[0][0]) / res[i].annotations.rightEyeIris[0][0];
const leftIrisCenterX = Math.abs(res[i].mesh[263][0] - res[i].annotations.leftEyeIris[0][0]) / res[i].annotations.leftEyeIris[0][0];
if (leftIrisCenterX > 0.033 || rightIrisCenterX > 0.033) center = false;
if (leftIrisCenterX > 0.033) gestures.push({ iris: i, gesture: 'looking right' });
if (rightIrisCenterX > 0.033) gestures.push({ iris: i, gesture: 'looking left' });
const rightIrisCenterX = Math.abs(res[i].mesh[33][0] - res[i].annotations.rightEyeIris[0][0]) / res[i].box[2];
const leftIrisCenterX = Math.abs(res[i].mesh[263][0] - res[i].annotations.leftEyeIris[0][0]) / res[i].box[2];
if (leftIrisCenterX > 0.06 || rightIrisCenterX > 0.06) center = false;
if (leftIrisCenterX > 0.06) gestures.push({ iris: i, gesture: 'looking right' });
if (rightIrisCenterX > 0.06) gestures.push({ iris: i, gesture: 'looking left' });
const rightIrisCenterY = Math.abs(res[i].mesh[145][1] - res[i].annotations.rightEyeIris[0][1]) / res[i].annotations.rightEyeIris[0][1];
const leftIrisCenterY = Math.abs(res[i].mesh[374][1] - res[i].annotations.leftEyeIris[0][1]) / res[i].annotations.leftEyeIris[0][1];
if (leftIrisCenterY < 0.015 || rightIrisCenterY < 0.015 || leftIrisCenterY > 0.030 || rightIrisCenterY > 0.030) center = false;
if (leftIrisCenterY < 0.015 || rightIrisCenterY < 0.015) gestures.push({ iris: i, gesture: 'looking down' });
if (leftIrisCenterY > 0.030 || rightIrisCenterY > 0.030) gestures.push({ iris: i, gesture: 'looking up' });
const rightIrisCenterY = Math.abs(res[i].mesh[145][1] - res[i].annotations.rightEyeIris[0][1]) / res[i].box[3];
const leftIrisCenterY = Math.abs(res[i].mesh[374][1] - res[i].annotations.leftEyeIris[0][1]) / res[i].box[3];
if (leftIrisCenterY < 0.01 || rightIrisCenterY < 0.01 || leftIrisCenterY > 0.025 || rightIrisCenterY > 0.025) center = false;
if (leftIrisCenterY < 0.01 || rightIrisCenterY < 0.01) gestures.push({ iris: i, gesture: 'looking down' });
if (leftIrisCenterY > 0.025 || rightIrisCenterY > 0.025) gestures.push({ iris: i, gesture: 'looking up' });
// still center;
if (center) gestures.push({ iris: i, gesture: 'looking center' });
console.log(leftIrisCenterX, rightIrisCenterX, leftIrisCenterY, rightIrisCenterY, gestures);
}
return gestures;
};