Skip to content

Commit d10dc02

Browse files
committed
Implement Harman's earlobe calculations
1 parent d30e048 commit d10dc02

File tree

2 files changed

+98
-22
lines changed

2 files changed

+98
-22
lines changed

js/detector/face_detector.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ export class FaceDetector extends Detector {
9494
name = "top_edge_face";
9595
break;
9696
}
97+
case 93: {
98+
name = "93";
99+
break;
100+
}
101+
case 132: {
102+
name = "132";
103+
break;
104+
}
105+
case 137: {
106+
name = "137";
107+
break;
108+
}
97109
case 152: {
98110
name = "bottom_edge_face";
99111
break;
@@ -102,10 +114,30 @@ export class FaceDetector extends Detector {
102114
name = "midpoint_between_nose_and_mouth";
103115
break;
104116
}
117+
case 177: {
118+
name = "177";
119+
break;
120+
}
105121
case 234: {
106122
name = "right_edge_face";
107123
break;
108124
}
125+
case 323: {
126+
name = "323";
127+
break;
128+
}
129+
case 361: {
130+
name = "361";
131+
break;
132+
}
133+
case 366: {
134+
name = "366";
135+
break;
136+
}
137+
case 401: {
138+
name = "401";
139+
break;
140+
}
109141
case 454: {
110142
name = "left_edge_face";
111143
break;

js/mesh.js

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,46 @@ export class Mesh {
303303
return this.earlobeKeypoints;
304304
}
305305

306+
const k93 = this.getKeypointByLabel("93");
307+
if (k93 == null) {
308+
return this.earlobeKeypoints;
309+
}
310+
311+
const k132 = this.getKeypointByLabel("132");
312+
if (k132 == null) {
313+
return this.earlobeKeypoints;
314+
}
315+
316+
const k137 = this.getKeypointByLabel("137");
317+
if (k137 == null) {
318+
return this.earlobeKeypoints;
319+
}
320+
321+
const k177 = this.getKeypointByLabel("177");
322+
if (k177 == null) {
323+
return this.earlobeKeypoints;
324+
}
325+
326+
const k323 = this.getKeypointByLabel("323");
327+
if (k323 == null) {
328+
return this.earlobeKeypoints;
329+
}
330+
331+
const k361 = this.getKeypointByLabel("361");
332+
if (k361 == null) {
333+
return this.earlobeKeypoints;
334+
}
335+
336+
const k366 = this.getKeypointByLabel("366");
337+
if (k366 == null) {
338+
return this.earlobeKeypoints;
339+
}
340+
341+
const k401 = this.getKeypointByLabel("401");
342+
if (k401 == null) {
343+
return this.earlobeKeypoints;
344+
}
345+
306346
/**
307347
* If an earring asset is being displayed on the an earlobe, we need to ensure that it is scaled correctly as
308348
* the user moves towards or away from the camera.
@@ -359,22 +399,17 @@ export class Mesh {
359399
* coordinates of the earlobes to be closer to edges of the face.
360400
*/
361401
let leftEarlobeX;
362-
if (isRotatedLeft) {
363-
leftEarlobeX = leftEar.getX();
364-
leftEarlobeX -= this.earlobeKeypoints[0].getWidth() / 2;
365-
leftEarlobeX += (Math.abs(leftEar.getX() - leftEdgeFace.getX()) / 2);
366-
} else {
367-
leftEarlobeX = leftEdgeFace.getX();
368-
}
402+
leftEarlobeX = k323.getX() + Math.abs(k366.getX() - k323.getX());
403+
leftEarlobeX += k361.getX() + Math.abs(k401.getX() - k361.getX());
404+
leftEarlobeX /= 2;
405+
leftEarlobeX -= this.earlobeKeypoints[0].getWidth() / 2;
406+
369407

370408
let rightEarlobeX;
371-
if (isRotatedRight) {
372-
rightEarlobeX = rightEar.getX();
373-
rightEarlobeX -= this.earlobeKeypoints[1].getWidth() / 2;
374-
rightEarlobeX += (Math.abs(rightEar.getX() - rightEdgeFace.getX()) / 2);
375-
} else {
376-
rightEarlobeX = rightEdgeFace.getX();
377-
}
409+
rightEarlobeX = k132.getX() - Math.abs(k132.getX() - k177.getX());
410+
rightEarlobeX += k93.getX() - Math.abs(k93.getX() - k137.getX());
411+
rightEarlobeX /= 2;
412+
rightEarlobeX += this.earlobeKeypoints[1].getWidth() / 2;
378413

379414
/*
380415
* We assume that the Y-Axis of each earlobe is the same as the midpoint between the nose and mouth.
@@ -383,27 +418,36 @@ export class Mesh {
383418
* the Y-Axis coordinates of the ears or eyes. Generally, Keypoints closer to the middle of the face are more
384419
* accurate, so we use the difference between the Y-Axis coordinates of the eyes.
385420
*/
386-
let leftEarlobeY = midPointBetweenNoseAndMouth.y + (leftEye.y - rightEye.y);
387-
let rightEarlobeY = midPointBetweenNoseAndMouth.y + (rightEye.y - leftEye.y);
421+
let leftEarlobeY = 0;
422+
leftEarlobeY = k323.getY() + Math.abs(k366.getY() - k323.getY());
423+
leftEarlobeY += k361.getY() + Math.abs(k401.getY() - k361.getY());
424+
leftEarlobeY /= 2;
425+
leftEarlobeY += this.earlobeKeypoints[0].getHeight() / 2;
426+
427+
let rightEarlobeY;
428+
rightEarlobeY = k132.getY() - Math.abs(k132.getY() - k177.getY());
429+
rightEarlobeY += k93.getY() - Math.abs(k93.getY() - k137.getY());
430+
rightEarlobeY /= 2;
431+
rightEarlobeY += this.earlobeKeypoints[1].getHeight() / 2;
388432

389433
// If the head is tilted up or down, we need to apply an offset to negate the tilt.
390-
leftEarlobeY += isRotatedUp ? topEdgeFace.z: 0;
391-
leftEarlobeY += isRotatedDown ? -bottomEdgeFace.z : 0;
434+
// leftEarlobeY += isRotatedUp ? topEdgeFace.z: 0;
435+
// leftEarlobeY += isRotatedDown ? -bottomEdgeFace.z : 0;
392436

393-
rightEarlobeY += isRotatedUp ? topEdgeFace.z : 0;
394-
rightEarlobeY += isRotatedDown ? -bottomEdgeFace.z : 0;
437+
// rightEarlobeY += isRotatedUp ? topEdgeFace.z : 0;
438+
// rightEarlobeY += isRotatedDown ? -bottomEdgeFace.z : 0;
395439

396440
/*
397441
* We assume that the X-Axis coordinate of the earlobe is the same as the X-Axis coordinate of the ear.
398442
*
399443
* We assume that head rotation is accounted for by the ear Keypoints, as their coordinates are updated by the
400444
* model.
401445
*/
402-
this.earlobeKeypoints[0].setConfidence(1);
446+
this.earlobeKeypoints[0].setConfidence(isRotatedRight ? 0 : 1);
403447
this.earlobeKeypoints[0].setPosition(leftEarlobeX, leftEarlobeY, leftEar.z);
404448
this.earlobeKeypoints[0].setColour(Mesh.defaultEarlobeKeypointColour);
405449

406-
this.earlobeKeypoints[1].setConfidence(1);
450+
this.earlobeKeypoints[1].setConfidence(isRotatedLeft ? 0 : 1);
407451
this.earlobeKeypoints[1].setPosition(rightEarlobeX, rightEarlobeY, rightEar.z);
408452
this.earlobeKeypoints[1].setColour(Mesh.defaultEarlobeKeypointColour);
409453

0 commit comments

Comments
 (0)