tt.createHandDetector收藏我的收藏
收藏
我的收藏基础库 1.66.0 开始支持本方法,这是一个同步方法。
创建一个手势识别器 Detector 实例对象
语法
tt.createHandDetector()
返回
Detector 对象
代码示例
IDE 不支持相关功能,请在手机上查看效果
function draw() {
let camera = tt.createCamera();
camera.start("front", true, { gesture: true }).then((video) => {
drawHand(video);
});
function drawHand(video) {
const canvas = tt.createCanvas();
const ctx = canvas.getContext("2d");
const detector = tt.createHandDetector();
const { width, height } = canvas;
const scalar = width / video.videoWidth;
video.height = (video.videoHeight * width) / video.videoWidth;
video.width = width;
var handInfo;
function doHandDetect() {
handInfo = detector.detect(video);
setTimeout(doHandDetect, 30);
}
function draw() {
requestAnimationFrame(draw);
video.paintTo(canvas, 0, 0, 0, 0, video.width, video.height);
ctx.textBaseline = "middle";
const txtarr = ["", "击拳", "鼓掌"];
if (handInfo) {
for (let i = 0; i < handInfo.length; i++) {
const y = i * 80 + 160;
var boundingBox = handInfo[i].boundingBox;
var txt =
"手势 " + (i + 1) + ": " + handInfo[i].actions + " 动态:" + handInfo[i].seqAction;
if (handInfo[i].seqAction > 0) {
ctx.font = "120px monospace";
ctx.fillStyle = "red";
ctx.fillText(
txtarr[handInfo[i].seqAction],
boundingBox.x * scalar,
boundingBox.y * scalar - 50,
);
}
ctx.font = "27px monospace";
ctx.lineWidth = 1;
ctx.fillStyle = "red";
ctx.fillRect(0, y - 20, ctx.measureText(txt).width + 30, 41);
ctx.fillStyle = "white";
ctx.fillText(txt, 20, y);
ctx.strokeStyle = "rgba(255,255,0,0.6)";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.rect(
boundingBox.x * scalar,
boundingBox.y * scalar,
boundingBox.width * scalar,
boundingBox.height * scalar,
);
ctx.stroke();
ctx.lineWidth = 3;
ctx.strokeStyle = "rgba(215, 255, 255,0.6)";
let keypoints = handInfo[i].keyPoints;
for (let i = 0; i < keypoints.length; i++) {
if (i == 0 || i == 5 || i == 9 || i == 13 || i == 17) {
if (i != 0) {
ctx.stroke();
}
ctx.beginPath();
ctx.moveTo(keypoints[0].x * scalar, keypoints[0].y * scalar);
}
if (
i <= 4 ||
(i > 4 && i <= 8) ||
(i > 8 && i <= 12) ||
(i > 12 && i <= 16) ||
(i > 16 && i <= 20)
) {
ctx.lineTo(keypoints[i].x * scalar, keypoints[i].y * scalar);
}
ctx.fillStyle = "purple";
ctx.fillText(i, keypoints[i].x * scalar + 10, keypoints[i].y * scalar);
ctx.fillStyle = "red";
ctx.fillRect(keypoints[i].x * scalar - 6, keypoints[i].y * scalar, 10, 10);
}
ctx.stroke();
}
}
}
draw();
doHandDetect();
}
}
draw();
使用提示
检测信息返回的坐标值可能需要进行缩放处理,缩放参数为:scalar
const { width, height } = canvas; //要绘制的canvas
const scalar = width / video.videoWidth; //video为摄像头返回的视频流对象
//例如,使用包围盒时,需要以下处理:
var boundindBoxX = boundingBox.x * scalar;
输出结果示意图
结果说明
1. 矩形框通过HandInfo.boundingBox画出
2. 22个手部关键点由HandInfo.key_points画出
3. 输出的 hand_open 为HandInfo.actions值
Bug & Tip
- Tip: 目前手势识别的输入数据仅支持摄像头。
- Tip: 手势识别的检测频率为 4 帧一次。
- Tip: 除了双手动作外,手势识别目前只支持单手识别,即同时出现两只手,手势识别只能识别先出现的手的动作。