justadudewhohacks / face-api.js

JavaScript API for face detection and face recognition in the browser and nodejs with tensorflow.js
MIT License
16.53k stars 3.69k forks source link

Is it possible to Measure Face Angle / Rotation? #724

Open sukant-kar opened 3 years ago

sukant-kar commented 3 years ago

Hi @justadudewhohacks ,

Awesome work! and thanks for building this awesome project, I'm having a doubt, please help me with that. Is it possible to Measure Face Angle / Rotation to detect face movements during webcam session?

For example If we want to know "Is user's mouth is opened or not", then we can calculate the axis difference between point 63 and 67

image

But how to know if user's face is 45 degree rotated, or say 30 degree rotated is there any way?

incredibleasif commented 3 years ago

I am also trying to do same. please check this link it might be helpful https://github.com/justadudewhohacks/face-api.js#retrieve-the-face-landmark-points-and-contours

sukant-kar commented 3 years ago

@incredibleasif I used this technique to find differences / distance between two coordinates in face but my question is how to detect face angle? Have you any idea for this? Any algo or kind of simple formulae?

sukant-kar commented 3 years ago

BTW, i am still waiting for author to get a reply here

MariasStory commented 3 years ago

Hi @sukant-kar, I am not sure what exactly you are looking for. But, if you are looking for an angle, you have to define your system of coordinates. To get an angle between the points 63 and 67 you need to use reference points. For example points 49 and 55 or 1 and 17, depending on the angle reference you are looking for. Draw a line between the reference points and the angle is a simple math.

amit0shakya commented 3 years ago

Try this

let x1 = point1.x;
let y1 = point1.y;

let x2= point17.x
let y2= point17.y;

let _m = (y2-y1)/(x2-x1)
let rad = Math.atan(_m)  
let ang = rad *(180/3.14)* (-1);

It works for me hopefully helpful for you guys.

vihar638 commented 2 years ago

You can use this code worked for me.

const detections = await faceapi.detectSingleFace(img, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceDescriptor().withFaceExpressions().withAgeAndGender();

var eye_right = getMeanPosition(detections["landmarks"].getRightEye());
var eye_left = getMeanPosition(detections["landmarks"].getLeftEye());
var nose = getMeanPosition(detections["landmarks"].getNose());
var mouth= getMeanPosition(detections["landmarks"].getMouth());
var jaw = getTop(detections["landmarks"].getJawOutline());

var rx = (jaw - mouth) / detections["_box"]["_height"];
var ry = (left_eye[0] + (right_eye[0] - left_eye[0]) / 2 - nose[0]) / detections["_box"]["_width"];

var face_val = ry.toFixed(2);

if(face_val < -0.06)
{
    //user moving in left direction
}
else if(face_val >= 0.07)
{
    //user moving in right direction    
}
else
{
    //user face in facing front side of webcam
}
CTSMixed commented 2 years ago

Thanks @Vihar638, but I am unabel to find the defn for the function getMeanPosition.. can u plz help with that?

vihar638 commented 2 years ago

I completely forgot to mention the function getMeanPosition here is the function @CTSMixed , may this help you `function getTop(l) { return l.map((a) => a.y).reduce((a, b) => Math.min(a, b)); }

function getMeanPosition(l) { return l.map((a) => [a.x, a.y]).reduce((a, b) => [a[0] + b[0], a[1] + b[1]]).map((a) => a / l.length); }`