UNPKG

kalidokit

Version:

Blendshape and kinematics calculator for Mediapipe/Tensorflow.js Face, Eyes, Pose, and Finger tracking models.

56 lines (55 loc) 2.32 kB
import Vector from "../utils/vector"; import { remap, clamp } from "../utils/helpers"; /** * Calculate Mouth Shape * @param {Array} lm : array of results from tfjs or mediapipe */ export const calcMouth = (lm) => { // eye keypoints const eyeInnerCornerL = new Vector(lm[133]); const eyeInnerCornerR = new Vector(lm[362]); const eyeOuterCornerL = new Vector(lm[130]); const eyeOuterCornerR = new Vector(lm[263]); // eye keypoint distances const eyeInnerDistance = eyeInnerCornerL.distance(eyeInnerCornerR); const eyeOuterDistance = eyeOuterCornerL.distance(eyeOuterCornerR); // mouth keypoints const upperInnerLip = new Vector(lm[13]); const lowerInnerLip = new Vector(lm[14]); const mouthCornerLeft = new Vector(lm[61]); const mouthCornerRight = new Vector(lm[291]); // mouth keypoint distances const mouthOpen = upperInnerLip.distance(lowerInnerLip); const mouthWidth = mouthCornerLeft.distance(mouthCornerRight); // mouth open and mouth shape ratios // let ratioXY = mouthWidth / mouthOpen; let ratioY = mouthOpen / eyeInnerDistance; let ratioX = mouthWidth / eyeOuterDistance; // normalize and scale mouth open ratioY = remap(ratioY, 0.15, 0.7); // normalize and scale mouth shape ratioX = remap(ratioX, 0.45, 0.9); ratioX = (ratioX - 0.3) * 2; // const mouthX = remap(ratioX - 0.4, 0, 0.5); const mouthX = ratioX; const mouthY = remap(mouthOpen / eyeInnerDistance, 0.17, 0.5); //Depricated: Change sensitivity due to facemesh and holistic have different point outputs. // const fixFacemesh = runtime === "tfjs" ? 1.3 : 0; // let ratioI = remap(mouthXY, 1.3 + fixFacemesh * 0.8, 2.6 + fixFacemesh) * remap(mouthY, 0, 1); const ratioI = clamp(remap(mouthX, 0, 1) * 2 * remap(mouthY, 0.2, 0.7), 0, 1); const ratioA = mouthY * 0.4 + mouthY * (1 - ratioI) * 0.6; const ratioU = mouthY * remap(1 - ratioI, 0, 0.3) * 0.1; const ratioE = remap(ratioU, 0.2, 1) * (1 - ratioI) * 0.3; const ratioO = (1 - ratioI) * remap(mouthY, 0.3, 1) * 0.4; return { x: ratioX || 0, y: ratioY || 0, shape: { A: ratioA || 0, E: ratioE || 0, I: ratioI || 0, O: ratioO || 0, U: ratioU || 0, }, }; };