Skip to content

Commit

Permalink
update release
Browse files Browse the repository at this point in the history
  • Loading branch information
vladmandic committed Oct 18, 2022
1 parent 0009d1b commit 15ae496
Show file tree
Hide file tree
Showing 198 changed files with 10,754 additions and 158,499 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @vladmandic/face-api

Version: **1.7.5**
Version: **1.7.6**
Description: **FaceAPI: AI-powered Face Detection & Rotation Tracking, Face Description & Recognition, Age & Gender & Emotion Prediction for Browser and NodeJS using TensorFlow/JS**

Author: **Vladimir Mandic <[email protected]>**
Expand All @@ -9,9 +9,13 @@

## Changelog

### **HEAD -> master** 2022/10/14 [email protected]
### **1.7.6** 2022/10/18 [email protected]


### **origin/master** 2022/10/18 [email protected]

- fix face angles (yaw, pitch, & roll) accuracy (#130)

### **1.7.5** 2022/10/09 [email protected]

- create funding.yml
Expand Down
11 changes: 1 addition & 10 deletions demo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ function faces(name, title, id, data) {
canvas.style.position = 'absolute';
canvas.style.left = `${img.offsetLeft}px`;
canvas.style.top = `${img.offsetTop}px`;
// @ts-ignore
canvas.width = img.width;
// @ts-ignore
canvas.height = img.height;
const ctx = canvas.getContext('2d');
if (!ctx) return;
Expand All @@ -53,6 +51,7 @@ function faces(name, title, id, data) {
ctx.beginPath();
ctx.rect(person.detection.box.x, person.detection.box.y, person.detection.box.width, person.detection.box.height);
ctx.stroke();
// draw text labels
ctx.globalAlpha = 1;
ctx.fillText(`${Math.round(100 * person.genderProbability)}% ${person.gender}`, person.detection.box.x, person.detection.box.y - 18);
ctx.fillText(`${Math.round(person.age)} years`, person.detection.box.x, person.detection.box.y - 2);
Expand Down Expand Up @@ -143,16 +142,9 @@ async function main() {
const engine = await faceapi.tf.engine();
log(`TF Engine State: ${str(engine.state)}`);

// const testT = faceapi.tf.tensor([0]);
// const testF = testT.toFloat();
// console.log(testT.print(), testF.print());
// testT.dispose();
// testF.dispose();

// loop through all images and try to process them
log(`Start processing: ${samples.length} images ...<br>`);
for (const img of samples) {
// new line
document.body.appendChild(document.createElement('br'));
// load and resize image
const canvas = await image(img);
Expand All @@ -178,7 +170,6 @@ async function main() {
print('SSDMobileNet:', img, dataSSDMobileNet);
} catch (err) {
log(`Image: ${img} Error during processing ${str(err)}`);
console.error(err); // eslint-disable-line no-console
}
}
}
Expand Down
30 changes: 5 additions & 25 deletions demo/webcam.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function drawFaces(canvas, data, fps) {
ctx.rect(person.detection.box.x, person.detection.box.y, person.detection.box.width, person.detection.box.height);
ctx.stroke();
ctx.globalAlpha = 1;
// const expression = person.expressions.sort((a, b) => Object.values(a)[0] - Object.values(b)[0]);
// draw text labels
const expression = Object.entries(person.expressions).sort((a, b) => b[1] - a[1]);
ctx.fillStyle = 'black';
ctx.fillText(`gender: ${Math.round(100 * person.genderProbability)}% ${person.gender}`, person.detection.box.x, person.detection.box.y - 59);
Expand All @@ -66,7 +66,6 @@ function drawFaces(canvas, data, fps) {
for (let i = 0; i < person.landmarks.positions.length; i++) {
ctx.beginPath();
ctx.arc(person.landmarks.positions[i].x, person.landmarks.positions[i].y, pointSize, 0, 2 * Math.PI);
// ctx.fillText(`${i}`, person.landmarks.positions[i].x + 4, person.landmarks.positions[i].y + 4);
ctx.fill();
}
}
Expand Down Expand Up @@ -100,29 +99,23 @@ async function setupCamera() {
const canvas = document.getElementById('canvas');
if (!video || !canvas) return null;

let msg = '';
log('Setting up camera');
// setup webcam. note that navigator.mediaDevices requires that page is accessed via https
if (!navigator.mediaDevices) {
log('Camera Error: access not supported');
return null;
}
let stream;
const constraints = {
audio: false,
video: { facingMode: 'user', resizeMode: 'crop-and-scale' },
};
const constraints = { audio: false, video: { facingMode: 'user', resizeMode: 'crop-and-scale' } };
if (window.innerWidth > window.innerHeight) constraints.video.width = { ideal: window.innerWidth };
else constraints.video.height = { ideal: window.innerHeight };
try {
stream = await navigator.mediaDevices.getUserMedia(constraints);
} catch (err) {
if (err.name === 'PermissionDeniedError' || err.name === 'NotAllowedError') msg = 'camera permission denied';
else if (err.name === 'SourceUnavailableError') msg = 'camera not available';
log(`Camera Error: ${msg}: ${err.message || err}`);
if (err.name === 'PermissionDeniedError' || err.name === 'NotAllowedError') log(`Camera Error: camera permission denied: ${err.message || err}`);
if (err.name === 'SourceUnavailableError') log(`Camera Error: camera not available: ${err.message || err}`);
return null;
}
// @ts-ignore
if (stream) video.srcObject = stream;
else {
log('Camera Error: stream empty');
Expand All @@ -133,31 +126,23 @@ async function setupCamera() {
if (settings.deviceId) delete settings.deviceId;
if (settings.groupId) delete settings.groupId;
if (settings.aspectRatio) settings.aspectRatio = Math.trunc(100 * settings.aspectRatio) / 100;
log(`Camera active: ${track.label}`); // ${str(constraints)}
log(`Camera active: ${track.label}`);
log(`Camera settings: ${str(settings)}`);
canvas.addEventListener('click', () => {
// @ts-ignore
if (video && video.readyState >= 2) {
// @ts-ignore
if (video.paused) {
// @ts-ignore
video.play();
detectVideo(video, canvas);
} else {
// @ts-ignore
video.pause();
}
}
// @ts-ignore
log(`Camera state: ${video.paused ? 'paused' : 'playing'}`);
});
return new Promise((resolve) => {
video.onloadeddata = async () => {
// @ts-ignore
canvas.width = video.videoWidth;
// @ts-ignore
canvas.height = video.videoHeight;
// @ts-ignore
video.play();
detectVideo(video, canvas);
resolve(true);
Expand All @@ -175,7 +160,6 @@ async function setupFaceAPI() {
await faceapi.nets.faceRecognitionNet.load(modelPath);
await faceapi.nets.faceExpressionNet.load(modelPath);
optionsSSDMobileNet = new faceapi.SsdMobilenetv1Options({ minConfidence: minScore, maxResults });

// check tf engine state
log(`Models loaded: ${str(faceapi.tf.engine().state.numTensors)} tensors`);
}
Expand All @@ -190,14 +174,10 @@ async function main() {

// default is webgl backend
await faceapi.tf.setBackend('webgl');

await faceapi.tf.enableProdMode();
await faceapi.tf.ENV.set('DEBUG', false);
await faceapi.tf.ready();

// check version
log(`Version: FaceAPI ${str(faceapi?.version || '(not loaded)')} TensorFlow/JS ${str(faceapi?.tf?.version_core || '(not loaded)')} Backend: ${str(faceapi?.tf?.getBackend() || '(not loaded)')}`);
// log(`Flags: ${JSON.stringify(faceapi?.tf?.ENV.flags || { tf: 'not loaded' })}`);

await setupFaceAPI();
await setupCamera();
Expand Down
Loading

0 comments on commit 15ae496

Please sign in to comment.