fun3dh
v1.0.6
Published
#### Via NPM
Downloads
2
Readme
Install
Via NPM
npm install fun3d
import * as fun3d from "fun3d";
// or only import the class you need
import { Face, Pose, Hand } from "fun3d";
方法
FUN3D由3个类组成,用于面部、姿势和手计算。他们接受来自Facemesh、Blazepose、Handpose和Obsolental等模型的里程碑式输出。
// Accepts an array(468 or 478 with iris tracking) of vectors
fun3d.Face.solve(facelandmarkArray, {
runtime: "tfjs", // `mediapipe` or `tfjs`
video: HTMLVideoElement,
imageSize: { height: 0, width: 0 },
smoothBlink: false, // smooth left and right eye blink delays
blinkSettings: [0.25, 0.75], // adjust upper and lower bound blink sensitivity
});
// Accepts arrays(33) of Pose keypoints and 3D Pose keypoints
fun3d.Pose.solve(poseWorld3DArray, poseLandmarkArray, {
runtime: "tfjs", // `mediapipe` or `tfjs`
video: HTMLVideoElement,
imageSize: { height: 0, width: 0 },
enableLegs: true,
});
// Accepts array(21) of hand landmark vectors; specify 'Right' or 'Left' side
fun3d.Hand.solve(handLandmarkArray, "Right");
// Using exported classes directly
Face.solve(facelandmarkArray);
Pose.solve(poseWorld3DArray, poseLandmarkArray);
Hand.solve(handLandmarkArray, "Right");
额外的方法
// Stabilizes left/right blink delays + wink by providing blenshapes and head rotation
fun3d.Face.stabilizeBlink(
{ r: 0, l: 1 }, // left and right eye blendshape values
headRotationY, // head rotation in radians
{
noWink = false, // disables winking
maxRot = 0.5 // max head rotation in radians before interpolating obscured eyes
});
// The internal vector math class
fun3d.Vector();
Basic Usage
根据您选择使用的姿势和人脸检测模型,实现可能会有所不同,但原理仍然相同。本例使用Mediapipe,将它们简洁地结合在一起
import * as fun3d from 'fun3d'
import '@mediapipe/holistic/holistic';
import '@mediapipe/camera_utils/camera_utils';
let holistic = new Holistic({locateFile: (file) => {
return `https://cdn.jsdelivr.net/npm/@mediapipe/[email protected]/${file}`;
}});
holistic.onResults(results=>{
// do something with prediction results
// landmark names may change depending on TFJS/Mediapipe model version
let facelm = results.faceLandmarks;
let poselm = results.poseLandmarks;
let poselm3D = results.ea;
let rightHandlm = results.rightHandLandmarks;
let leftHandlm = results.leftHandLandmarks;
let faceRig = fun3d.Face.solve(facelm,{runtime:'mediapipe',video:HTMLVideoElement})
let poseRig = fun3d.Pose.solve(poselm3d,poselm,{runtime:'mediapipe',video:HTMLVideoElement})
let rightHandRig = fun3d.Hand.solve(rightHandlm,"Right")
let leftHandRig = fun3d.Hand.solve(leftHandlm,"Left")
};
});
// use Mediapipe's webcam utils to send video to holistic every frame
const camera = new Camera(HTMLVideoElement, {
onFrame: async () => {
await holistic.send({image: HTMLVideoElement});
},
width: 640,
height: 480
});
camera.start();
由于Mediapipe和Tensorflow.js的结果略有不同
由于Mediapipe和Tensorflow的结果略有不同,建议指定您使用的运行时版本以及视频输入/图像大小作为参考。
fun3d.Pose.solve(poselm3D,poselm,{
runtime:'tfjs', // default is 'mediapipe'
video: HTMLVideoElement,// specify an html video or manually set image size
imageSize:{
width: 640,
height: 480,
};
})
fun3d.Face.solve(facelm,{
runtime:'mediapipe', // default is 'tfjs'
video: HTMLVideoElement,// specify an html video or manually set image size
imageSize:{
width: 640,
height: 480,
};
})
输出
以下是fun3d解算器的预期结果
// fun3d.Face.solve()
// Head rotations in radians
// Degrees and normalized rotations also available
{
eye: {l: 1,r: 1},
mouth: {
x: 0,
y: 0,
shape: {A:0, E:0, I:0, O:0, U:0}
},
head: {
x: 0,
y: 0,
z: 0,
width: 0.3,
height: 0.6,
position: {x: 0.5, y: 0.5, z: 0}
},
brow: 0,
pupil: {x: 0, y: 0}
}
// fun3d.Pose.solve()
// Joint rotations in radians, leg calculators are a WIP
{
RightUpperArm: {x: 0, y: 0, z: -1.25},
LeftUpperArm: {x: 0, y: 0, z: 1.25},
RightLowerArm: {x: 0, y: 0, z: 0},
LeftLowerArm: {x: 0, y: 0, z: 0},
LeftUpperLeg: {x: 0, y: 0, z: 0},
RightUpperLeg: {x: 0, y: 0, z: 0},
RightLowerLeg: {x: 0, y: 0, z: 0},
LeftLowerLeg: {x: 0, y: 0, z: 0},
LeftHand: {x: 0, y: 0, z: 0},
RightHand: {x: 0, y: 0, z: 0},
Spine: {x: 0, y: 0, z: 0},
Hips: {
worldPosition: {x: 0, y: 0, z: 0},
position: {x: 0, y: 0, z: 0},
rotation: {x: 0, y: 0, z: 0},
}
}
// fun3d.Hand.solve()
// Joint rotations in radians
// only wrist and thumb have 3 degrees of freedom
// all other finger joints move in the Z axis only
{
RightWrist: {x: -0.13, y: -0.07, z: -1.04},
RightRingProximal: {x: 0, y: 0, z: -0.13},
RightRingIntermediate: {x: 0, y: 0, z: -0.4},
RightRingDistal: {x: 0, y: 0, z: -0.04},
RightIndexProximal: {x: 0, y: 0, z: -0.24},
RightIndexIntermediate: {x: 0, y: 0, z: -0.25},
RightIndexDistal: {x: 0, y: 0, z: -0.06},
RightMiddleProximal: {x: 0, y: 0, z: -0.09},
RightMiddleIntermediate: {x: 0, y: 0, z: -0.44},
RightMiddleDistal: {x: 0, y: 0, z: -0.06},
RightThumbProximal: {x: -0.23, y: -0.33, z: -0.12},
RightThumbIntermediate: {x: -0.2, y: -0.19, z: -0.01},
RightThumbDistal: {x: -0.2, y: 0.002, z: 0.15},
RightLittleProximal: {x: 0, y: 0, z: -0.09},
RightLittleIntermediate: {x: 0, y: 0, z: -0.22},
RightLittleDistal: {x: 0, y: 0, z: -0.1}
}