如何让HandTrack.js中的runDetection函数每2秒执行一次?
HandTrack.js手势检测定时器不生效问题解决方案
问题根因
你的代码出现执行频率过高的核心原因是存在两处错误的定时器逻辑:
- 重复创建定时器:
startVideo中已经创建了一个周期执行runDetection的定时器,但runDetection内部又嵌套了新的setInterval,每次执行都会新增一个定时器,多个定时器叠加后执行频率完全失控 requestAnimationFrame使用错误:requestAnimationFrame(回调)会立即在下一帧执行回调,你将它直接作为setInterval的参数,相当于完全忽略定时时长,直接触发runDetection执行,同时还会形成高频执行链- 定时时长不匹配:你需要2秒执行一次,但代码中写的是3000毫秒(3秒)
修复方案
直接移除runDetection内部多余的定时器逻辑,可选新增定时器id存储,方便停止视频时清理定时器避免内存泄漏,修改后的代码如下:
const video = document.getElementById("myvideo"); const canvas = document.getElementById("canvas"); const context = canvas.getContext("2d"); let trackButton = document.getElementById("trackbutton"); let updateNote = document.getElementById("updatenote"); let isVideo = false; let model = null; // 存储定时器id,方便清理 let detectionTimer = null; let headers = new Headers(); headers.append('Content-Type', 'application/json'); headers.append('Accept', 'application/json'); headers.append('Access-Control-Allow-Origin', 'http://127.0.0.1:8080'); headers.append('Access-Control-Allow-Credentials', 'true'); const modelParams = { flipHorizontal: true, // flip e.g for video maxNumBoxes: 20, // maximum number of boxes to detect iouThreshold: 0.5, // ioU threshold for non-max suppression scoreThreshold: 0.6, // confidence threshold for predictions. modelType: "ssd320fpnlite", bboxLineWidth: "2", fontSize: 17, } function startVideo() { handTrack.startVideo(video).then(function (status) { console.log("video started", status); if (status) { updateNote.innerText = "Video started. Now tracking" isVideo = true // 定时时长改为2000毫秒,存储定时器id detectionTimer = setInterval(runDetection, 2000) } else { updateNote.innerText = "Please enable video" } }); } function toggleVideo() { if (!isVideo) { updateNote.innerText = "Starting video" startVideo(); } else { updateNote.innerText = "Stopping video" handTrack.stopVideo(video) isVideo = false; // 停止视频时清理定时器 clearInterval(detectionTimer); updateNote.innerText = "Video stopped" } } function runDetection() { model.detect(video).then(predictions => { console.log(predictions); if(predictions.length !==0){ let label = predictions[0].label; let score = predictions[0].score; console.log(`Label: ${label}\nScore: ${score}`); if (label == "closed") { console.log("Closed"); } else { console.log("Not Closed"); } } model.renderPredictions(predictions, canvas, context, video); // 移除了内部多余的定时器和requestAnimationFrame逻辑 }); } // Load the model. handTrack.load(modelParams).then(lmodel => { // detect objects in the image. model = lmodel updateNote.innerText = "Loaded Model!" trackButton.disabled = false });
效果说明
修改后runDetection会严格每2秒执行一次,检测到手势为闭合状态时就会每2秒打印一次Closed,符合需求。
内容的提问来源于stack exchange,提问作者Ayaan
相关产品推荐
相关产品推荐

