浏览器集成Webcam实现人脸检测AI故障排查求助
浏览器实时人脸检测AI无法运行的解决方案
问题概述
尝试复现YouTube上的人脸检测AI,目标是在浏览器中集成摄像头实时展示检测结果,使用VS Code的Live-Server预览代码,但功能无法正常运行。已完成以下排查:
- 修改代码中摄像头分辨率为支持参数
- 更换分辨率高于640×480的摄像头
- 授予浏览器全部权限
- 禁用所有浏览器扩展
- 更换不同浏览器
- 使用不同的摄像头视频调用函数
问题代码
JavaScript代码
const video = document.getElementById('video') Promise.all([ faceapi.nets.tinyFaceDetector.loadFromUri('/models'), faceapi.nets.faceLandmark68Net.loadFromUri('/models'), faceapi.nets.faceRecognitionNet.loadFromUri('/models'), faceapi.nets.faceExpressionNet.loadFromUri('/models') ]).then(startVideo) function startVideo() { navigator.mediaDevices.getUserMedia( { video: true }, stream => video.srcObject = stream, err => console.error(err) ) } video.addEventListener('play', () => { const canvas = faceapi.createCanvasFromMedia(video) document.body.append(canvas) const displaySize = { width: video.width, height: video.height } faceapi.matchDimensions(canvas, displaySize) setInterval(async () => { const detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceExpressions() const resizedDetections = faceapi.resizeResults(detections, displaySize) canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height) faceapi.draw.drawDetections(canvas, resizedDetections) faceapi.draw.drawFaceLandmarks(canvas, resizedDetections) faceapi.draw.drawFaceExpressions(canvas, resizedDetections) }, 100) })
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script defer src="face-api.min.js"></script> <script defer src="script.js"></script> <style> body { margin: 0; padding: 0; width: 100vw; height: 100vh; display: flex; justify-content: center; align-items: center; } canvas { position: absolute; } </style> </head> <body> <video id="video" width="640" height="480" autoplay muted></video> </body> </html>
修复方案
1. 确认模型文件路径
确保/models文件夹与index.html处于同一层级,Live-Server的根目录即为项目根目录,若模型放在子文件夹中需调整loadFromUri路径(比如./models)。可打开浏览器开发者工具的Network面板,检查模型文件是否加载成功(状态码200)。
2. 优化摄像头调用逻辑
将getUserMedia改为async/await写法,确保错误能被完整捕获,同时指定明确的分辨率参数提升兼容性:
async function startVideo() { try { const stream = await navigator.mediaDevices.getUserMedia({ video: { width: 640, height: 480 } }); video.srcObject = stream; } catch (err) { console.error('摄像头调用失败:', err); } }
3. 修正视频尺寸与事件监听逻辑
video.width/video.height是HTML属性设置的尺寸,实际播放的视频分辨率可能不同,应使用video.videoWidth/video.videoHeight获取真实分辨率;同时将play事件改为playing事件,确保视频已完成加载再启动检测:
video.addEventListener('playing', () => { const canvas = faceapi.createCanvasFromMedia(video); document.body.append(canvas); // 获取视频实际分辨率 const displaySize = { width: video.videoWidth, height: video.videoHeight }; faceapi.matchDimensions(canvas, displaySize); // 用requestAnimationFrame替代setInterval,性能更稳定 async function detectFaces() { try { const detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()) .withFaceLandmarks() .withFaceExpressions(); const resizedDetections = faceapi.resizeResults(detections, displaySize); canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height); faceapi.draw.drawDetections(canvas, resizedDetections); faceapi.draw.drawFaceLandmarks(canvas, resizedDetections); faceapi.draw.drawFaceExpressions(canvas, resizedDetections); } catch (err) { console.error('人脸检测失败:', err); } requestAnimationFrame(detectFaces); } detectFaces(); });
4. 验证face-api.js文件有效性
确保face-api.min.js已正确下载并放在项目根目录,可通过开发者工具的Console面板查看是否有faceapi未定义的报错。
内容的提问来源于stack exchange,提问作者N_Radziszewski
相关产品推荐
相关产品推荐

